用于获取修改对象的 LINQ 表达式
本文关键字:LINQ 表达式 对象 获取 修改 用于 | 更新日期: 2023-09-27 18:32:13
我有一个地址列表,而地址定义如下:
public class Address
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime ModifiedDate { get; set; }
}
根据之前的调用,我有一个元组列表,而元组由地址 id 和修改日期组成。
e.g. List<Tuple<int, DateTime>>
现在我想获取所有具有相应 id 的地址,但前提是它们已被修改。
我已经将元组列表转换为包含 id 和字典的 int 数组,而 id 是键,修改日期是值。
int[] ids;
Dictionary<int, DateTime> dates;
以下内容足以获取具有相应 id 的所有地址。
addressList.Where(a => ids.Contains(a.Id));
很遗憾,以下情况是不可能的:
异常:"LINQ to Entities 无法识别方法'System.DateTime get_Item(Int32)'方法,并且此方法无法转换为存储表达式。
addressList.Where(a => ids.Contains(a.Id) && dates[a.Id] < a.ModifiedDate);
这个问题可以通过循环解决,但我正在寻找一个更优雅的解决方案。
List<Address> modifiedAddressList = new List<Address>();
foreach (Address a in addressList)
{
if (a.ModifiedDate > dates[a.Id]) modifiedAddressList.Add(a);
}
您的应用程序中有一些信息,数据库中有一些当前日期。 您需要将两者放在同一个位置才能比较两个数据集。 这意味着要么将字典中的信息传递到数据库,要么在进行比较之前将数据从数据库带回应用程序。
如果你想把你的数据发送到数据库,它需要通过SQL来完成;你的数据库不能只运行任何旧的C#代码,这就是你似乎试图做的,也是它不起作用的原因。
"更简单"的解决方案可能是做你似乎不太喜欢的事情,即从数据库中提取数据,然后在应用程序中过滤它。 另一种选择是将字典中的数据上传到临时表,然后将两个表连接在一起。
如果您愿意,可以用更多的 LINQ-esk 方式执行第一个选项:
addressList.Where(a => ids.Contains(a.Id))
.AsEnumerable()
.Where(a => dates[a.Id] < a.ModifiedDate);
AsEnumerable
调用将确保后续方法在应用程序中执行,而不是转换为 SQL。 Contains
检查可以转换为 SQL 中的 IN 子句,因此它应该在 AsEnumerable
调用之前,以便在数据库端完成。
这里的问题是 LinqToEntities 不了解您的字典 - 以及如何将其转换为数据库查询。
您有以下几种选择:
- 遍历每个项目(如您所建议的)
- 传入已修改记录的 ID
- 将整个数据集下载到客户端(使用 ToList()),然后使用字典方法
选项 #3 非常简单 - 如果您不处理大型数据集:
addressList
.Where(a => ids.Contains(a.Id))
.AsEnumerable()
.Where(dates[a.Id] < a.ModifiedDate);