LINQ to SQL异常:本地序列不能用于查询运算符的LINQ to SQL实现中,Contains运算符除外
本文关键字:LINQ 运算符 SQL to 实现 Contains 不能 异常 用于 查询 | 更新日期: 2023-09-27 18:24:08
我知道这在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;
}