LINQ-模拟in子句中的多列
本文关键字:子句 模拟 in LINQ- | 更新日期: 2023-09-27 18:20:01
在oracle中,我可以执行以下查询:
SELECT *
FROM Tabl Tabb
WHERE (tabb.Col1, tabb.Col2) IN ( (1,2), (3,4))
假设我有以下实体:
public class Tabb
{
public int Col1 {get; set; }
public int Col2 {get; set; }
// other props
}
和标准类
public class Search
{
public int Col1 {get; set; }
public int Col2 {get; set; }
}
我需要写:
public IEnumerable<Tabb> Select(IEnumerable<Search> s)
{
var queryable = this.context.Tabbs;
return queryable.Where('* some *').ToList();
}
如果搜索集合包含具有相同值Col1
和Col2
的搜索实例,我如何选择实体?
编辑:
var result = from x in entity
join y in entity2
on new { x.field1, x.field2 } equals new { y.field1, y.field2 }
它不起作用(正如我所料)-在可能的情况下,entity2
不是实体表,它是静态集合,所以EF抛出异常(比如:找不到要键入Search[]的映射层);
有几种方法,它们都有优缺点,有时有点棘手。。。
解决方案1
首先枚举ef部分(当然,根据数据的大小,这可能是一个非常糟糕的主意)
解决方案2
您将字段与您确信在字段中找不到的元素(哼)连接起来,并在连接的EF数据上使用Contains。
var joinedCollection =entity2.Select(m => m.field1 + "~" + m.field2);
var result = entity.Where(m => joinedCollection.Contains(m.field1 + "~" + m.field2));
当然,如果field1和field2不是字符串,这会有点复杂,你必须使用类似的东西
SqlFunctions.StringConvert((double)m.field1) + "~" + //etc.
解决方案3
你可以分两步来完成,假设你的部分匹配(只在一个字段上)"不会有太多结果"
var field1Collection = joinedCollection.Select(m => m.field1);
var result = entity.Where(m => joinedCollection.Contains(m.field1)).ToList();
然后对两个枚举列表进行"完全联接"。。。
解决方案4
使用存储过程/生成的原始sql。。。
只是更好地理解了这个问题。你想要列匹配的所有行,这可能会有所帮助:
myDBTable.Where(x =>
myStaticCollection.Any(y => y.Col2 == x.Col2) &&
myStaticCollection.Any(y => y.Col1 == x.Col1))
.ToList()
.Select(x => new Search { Col1 = x.Col1, Col2 = x.Col2 });
也就是说,我希望静态集合中任何Col2
与该数据库Col2
匹配的每一行,以及任何Col1
与该数据库Col1
匹配的每行
this.context.Searches.Join(
this.context.Tabbs,
s => s.Col2,
t => t.Col2,
(search, tab) => new {
search,
tab
});
这将返回包含搜索和选项卡的IEnumerable<'a>
这家伙正在做类似的链接
var result = from x in entity
join y in entity2
on new { x.field1, x.field2 } equals new { y.field1, y.field2 }
一旦你有了result
,你就需要枚举它,以确保你正在访问数据库并取回所有的值。一旦它们在内存中,就可以将它们投影到对象中。
result.ToList().Select(a => new MyEntity { MyProperty = a.Property });