Ada*_*gen 7 c# sql linq performance entity-framework
在EF中,如果我有一个灵长类型列表(List),那么对表的"加入"很容易:
var ids = int[]{1,4,6}; //some random values
var rows = context.SomeTable.Where(r => ids.Contains(r.id))
Run Code Online (Sandbox Code Playgroud)
在您想要加入多个列的瞬间,这会变得更加复杂:
var keys = something.Select(s => new { s.Field1, s.Field2 })
var rows = context.SomeTable.Where(r => keys.Contains(r => new { s.Field1, s.Field2 })); // this won't work
Run Code Online (Sandbox Code Playgroud)
我找到了两种方法来加入它,但两者都不是很好:
有时,我能够做出的妥协是修改#1:基于一个相当独特的密钥拉入表的子集
var keys = something.Select(s => s.Field1)
var rows = context.SomeTable.Where(r => keys.Contains(s.Field1)).ToList();
foreach (var sRow in something)
{
var joinResult = rows.Where(r => r.Field1 == sRow.Field1 && r.Field2 == sRow.Field2);
//do stuff
}
Run Code Online (Sandbox Code Playgroud)
但即便如此,这也可能会导致数据过多.
我知道有一些方法可以将表值参数哄骗到ADO.Net中,以及我可以构建一系列OR一起使用的.Where()子句的方法.有没有人有魔法子弹?
您可以尝试压平按键,然后使用相同的Contains
图案。尽管您可以使用函数索引将扁平化的键存储在数据库中,但这在大型查询上可能表现不佳......
我有带列的表测试K1 int, K2 int, Name varchar(50)
var l = new List<Tuple<int, int>>();
l.Add(new Tuple<int, int>(1, 1));
l.Add(new Tuple<int, int>(1, 2));
var s = l.Select(k => k.Item1.ToString() + "," + k.Item2.ToString());
var q = Tests.Where(t => s.Contains(t.K1.ToString() + "," + t.K2.ToString()));
foreach (var y in q) {
Console.WriteLine(y.Name);
}
Run Code Online (Sandbox Code Playgroud)
我已经在 LinqPad 中使用 Linq to SQL 对此进行了测试
第一次尝试没有成功:
我认为将其编写为单个查询的方法是这样的
var keys = something.Select(s => new { s.Field1, s.Field2 })
var rows = context.SomeTable.Where(r => keys.Any(k => r.Field1 == k.Field1 && r.Field2 == k.Field2));
Run Code Online (Sandbox Code Playgroud)
不幸的是,我在这台笔记本电脑上没有 EF,甚至无法测试这在语法上是否正确。
我也不知道它的性能如何,如果它真的有效的话......