1

我知道这是 SO 的副本,但我不知道如何在我的特定代码中使用 contains 运算符:

我在数据库中有 5 个预订:

ID, Booking, Pren, ReservationCode

1, 访问这里, 1, 1000A

2, 访问这里, 1, 1000A

3, 访问这里, 1, 1000A

4, VisitThere, 2, 2000A

5, VisitThere, 2, 2000A

    public int SpecialDelete(DataContext db, IEnumerable<BookingType> bookings) {

        var rescodes = (from b in bookings
                        select b).Distinct().ToArray();
        // Code Breaks here
        IEnumerable<BookingType> bookingsToDelete = db.GetTable<BookingType>().Where(b => bookings.Any(p => p.Pren == b.Pren && p.ReservationCode == b.ReservationCode));

        int deleted = bookingsToDelete.Count();
        db.GetTable<BookingType>().DeleteAllOnSubmit(bookingsToDelete);
        db.SubmitChanges();

        return deleted;
    }

当我将第一条记录传递给此方法(1、VisitHere、1、1000A)时,我希望它检索 id 1、2 和 3,而不是 4 和 5。

我可以通过匹配 Pren 和 ReservationCode 来做到这一点。

当 .Any 和 .All 运营商抛出上述异常时,我该怎么做?

注意:该方法必须接受预订列表,因为参数将始终是传递给该方法的多个预订,我仅以单个预订为例。

编辑:我基本上需要 LINQ2SQL 来生成一堆这样的 SQL 语句(假设我想删除数据库中的所有记录):

DELETE
FROM Bookings b
WHERE b.ReservationCode = '1000A' AND b.Pren = 1

DELETE
FROM Bookings b
WHERE b.ReservationCode = '2000A' AND b.Pren = 2
4

3 回答 3

1

如果您在服务器上有一个准临时表怎么办。您可以将列表值放在那里。

这是 ORM 的一个真正问题。您有很多本地和远程功能之间的不匹配。

我什至尝试使用 .Range 生成要加入的远程列表,但它也不起作用。

本质上,您必须以某种方式重新排列您的数据孤岛(即 pren 和 rs 的列表来自哪里?它在服务器上的某个地方吗?)或将您的本地集合之一上传到服务器上的暂存区域。

于 2013-07-19T16:54:51.617 回答
1

您得到的错误是试图指导您使用 .Contains 方法传入一个简单的数组。默认情况下,它将该数组转换为In以下格式的子句:

Where foo In ("b1", "B2", "B3")

请注意,您不能在 In 子句中执行多维数组(您需要这样做)。由于您无法将服务器端加入本地阵列,因此只要您具有复合键关系,您的选择就会受到限制。

如果您不需要获取行来删除它们,那么使用 Context 的 ExecuteCommand 来发出删除可能会更快。只需确保参数化您的查询(请参阅http://www.thinqlinq.com/Post.aspx/Title/Does-LINQ-to-SQL-eliminate-the-possibility-of-SQL-Injection

string deleteQuery = "DELETE FROM Bookings b WHERE b.ReservationCode = {0} AND b.Pren = {1}";
foreach (var bookingType in bookings)
{
    db.ExecuteCommand(deleteQuery, bookingType.ReservationCode, bookingType.Preen);
}
于 2013-07-19T21:12:05.953 回答
0

错误消息显示“除了包含运算符”。您是否考虑过使用 Contains 运算符?它应该做同样的事情。

所以从

IEnumerable<BookingType> bookingsToDelete = db.GetTable<BookingType>().Where(b => bookings.Any(p => p.Pren == b.Pren && p.ReservationCode == b.ReservationCode));

IEnumerable<BookingType> bookingsToDelete = db.GetTable<BookingType>().Where(b => bookings.Contains(p => p.Pren == b.Pren && p.ReservationCode == b.ReservationCode));

我意识到该列表不会包含相同的对象,因此您可能需要执行以下操作:

bookings.Select(booking => booking.PrimaryKeyOfAwesome).Contains(b => b.PrimaryKeyOfAwesome) etc etc. 


为清晰起见进行了编辑

谦虚地编辑 好的,所以在实际重新创建整个设置之后,我意识到我的解决方案由于两个参数而不起作用,而不仅仅是一个。道歉。这是我最终想出的,它有效,但确实是一个糟糕的解决方案,不应该使用。我把它放在这里只是为了结束;)

        public static int SpecialDelete(DataContext db, IEnumerable<BookingType> bookings)
        {
            var compositeKeys = bookings.Select(b => b.Pren.ToString() + b.ReservationCode).Distinct();
            IEnumerable<BookingType> bookingsToDelete = db.GetTable<BookingType>().Where(b => compositeKeys.Contains(b.Pren.ToString() + b.ReservationCode));

            int deleted = bookingsToDelete.Count();
            db.GetTable<BookingType>().DeleteAllOnSubmit(bookingsToDelete);
            db.SubmitChanges();

            return deleted;
        }
于 2013-07-19T16:28:06.557 回答