LINQ to SQL异常:本地序列不能用于查询运算符的LINQ to SQL实现中,Contains运算符除外



我知道这在SO上是重复的,但我不知道如何在我的特定代码中使用包含运算符:

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

ID,预订,Pren,预订代码

1,访问此处,1000A

2,访问此处,1000A

3,访问此处,1000A

4,VisitTre,2000A

5,VisitTre,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,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

您收到的错误是试图指示您使用在一个简单数组中传递的.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);
}

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

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

我甚至尝试过使用.Range生成一个远程列表来加入,但也不起作用。

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

错误消息显示"except The contains operator"。您考虑过使用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;
        }

最新更新