我希望通过不调用相同查询的10.000倍(实际数字)来优化我的查询调用。
var myObject= _db.myObject.FirstOrDefault(x => x.property1 == param1 && x.property2 == param2 && x.property3 == 3);
所以我想
让我们将myOtherObject列表传递给一个函数。 myOtherObject包含通常填充param1,2和3的字段。
在普通查询中,我会在foreach中创建一个字符串并将其连接起来。像这样:
// WHERE (property1 = param1 && property2 = param2 && property3 = param3) OR (property1 = param1 && property2 = param2 && property3 = param3) OR (property1 = param1 && property2 = param2 && property3 = param3)
如何在LINQ中进行相同的操作(如果可能)。 是否可以连接多个OR
当然,我尝试与任何人联系并尝试过哪些但是因为它创建了AND语句(逻辑上)所以没有用。
上下文
我自己的数据库中有一个对象。我需要与数据库中的另一个对象进行比较,我只有只读访问权限。我可以在3个参数的组合上匹配这两个对象。
INPUT
ObjectA的列表(需要匹配的3个字段)
输出
从另一个(只读)数据库我想要一个匹配对象的列表。
答案 0 :(得分:1)
虽然您可以使用System.Linq.Expressions
APIs为LINQ构建表达式,但更简单的方法可能会起作用,具体取决于目标数据库中各个属性的选择性。
首先,请注意,如果另一个集合也在内存中,则查找与一组内存中对象匹配的任务非常简单:
// Type parameters of Tuple<,,> depend on the types of Prop1..Prop3
var expect = new HashSet<Tuple<string,string,string>>(
targetList.Select(item => Tuple.Create(item.Prop1, item.Prop2, item.Prop3))
);
var matches = sourceList
.Where(item => expect.Contains(Tuple.Create(item.Prop1, item.Prop2, item.Prop3)))
.ToList();
由于上述方法无法在数据库搜索中使用,因此请考虑采用两阶段方法:
您可以通过查询各个参数来获取误报项目列表,如下所示:
var p1List = targetList.Select(item => item.Prop1).ToList();
var p2List = targetList.Select(item => item.Prop2).ToList();
var p3List = targetList.Select(item => item.Prop3).ToList();
var preliminary = dbContext.BigTable
.Where(item => p1List.Contains(item.Prop1)
&& p2List.Contains(item.Prop2)
&& p3List.Contains(item.Prop3))
.AsEnumerable();
只要数据库查询将列表缩小到实际结果大小的十倍以下,这种方法就会起作用,因为内存查询在CPU使用方面非常有效(其效率为O( M + N),其中M是具有误报的列表的大小,N是目标列表的大小。
答案 1 :(得分:0)
对于未来面临此问题的人:我使用linq contains
解决了这个问题public async Task<List<MyObject>> GetMyObjectByListOfStrings(List<string> search)
{
var myObjects = await _db.Entity.Where(x => search.Contains(x.param1+ x.param2+ x.param3)).ToListAsync();
return myObjects;
}
可能有更好的选择,应该更改的设计或应该修复的实际问题。