c# LINQ单查询完成一个不完整的模型



我有一份不完整的产品型号列表。每个人都缺少一个主人和一个价格。这些缺陷可以通过对上下文的单个查询来填补吗?没有这个foreach循环?

foreach(var item in products)
{
item.Owner = context.Products.Where(x => x.Id == item.Id).Select(x => x.ProductOwner).FirstOrDefault();
item.Price = context.Products.Where(x => x.Id == item.Id).Select(x => x.ProductPrice).FirstOrDefault();
}

我想要一个查询来填写IEnumerable产品中的缺失字段


// build list of Id for which we need data
var idsToUpdate = products.Select(o => o.Id).ToList();
var dataById = Context.Products
// get matching entries (server side)
.Where(x => idsToUpdate.Contains(x.Id))
// get only relevant data
.Select(x => new { x.Id, x.ProductOwner, x.Price })
// ensure uniqueness (server side, free if Id is a PK)
.DistinctBy(x => x.Id)
// we will not update db
.AsNoTracking()
// now client side
.AsEnumerable()
// arrange the data
.ToDictionary(x => x.Id, x => new { x.ProductOwner, x.Price });
foreach (var item in products)
{
if (!dataById.TryGetValue(item.Id, out var data))
continue;
item.ProductOwner = data.ProductOwner;
item.Price = data.Price;
}

如果数据不多,那么尝试查询一次,也许?

  1. 选择所有目标id
  2. 从DB获取所有产品
  3. 随心所欲地使用您拥有的数据(两个列表)

ref:使用LINQ,是否可以从Select语句输出动态对象?如果有,怎么做?

Since "products"来自于外部服务和"环境"。是你的DB。为什么不加入context. products ?与"products"并返回"产品"的属性。通过为"所有者"申请价值和"price".

例子
var result = (from p in products 
join dbP in context.Products on dbP.Id == p.Id into gj 
from subDbP in gj.DefaultIfEmpty() 
select new { 
Owner = subDbP?.ProductOwner ?? string.Empty, 
Price = subDbP?.ProductPrice ?? string.Empty, 
Id = p.Id
}).ToList(); 

这很大程度上取决于产品的DataType。如果这是一个List,则有一个方法可用,称为ForEach。

如果你使用不同的东西,你必须在代码的某个地方写一个扩展方法。可以是这样的:

public static class EnumerableExtensions
{
public static void ForEach<T>(this IEnumerable<T> values, Action<T> predicate)
{
foreach(var value in values)
{
predicate(value);
}
}       
}
之后,你可以使用这个扩展方法,如LINQ:
products.ForEach(item => 
{
var product = context.Products.Where(x => x.Id == item.Id);
item.Owner = product.Select(x => x.ProductOwner).FirstOrDefault();
item.Price = product.Select(x => x.ProductPrice).FirstOrDefault();
});

希望有帮助:-)

最新更新