我对Entity Framework 6.0相对较新,我遇到过一种情况,我想在我的C#app中执行一个类似于这个SQL查询的查询:
select * from periods where id in (select distinct periodid from ratedetails where rateid = 3)
实际上是否可以在EF中执行这样的查询,还是需要将其分解为更小的步骤?
答案 0 :(得分:1)
假设您已进入Context
班级:
DbSet<Period> Periods...
DbSet<RateDetail> RateDetails...
你可以像这样使用一些Linq
:
var distincts = dbContext.RateDetails
.Where(i => i.rateId == 3)
.Select(i => i.PeriodId)
.Distinct();
var result = dbContext.Periods
.Where(i => i.Id)
.Any(j => distincts.Contains(j.Id));
修改:根据您的实体,您可能需要Comparer
的自定义Distinct()
。您可以找到教程here以及here
或使用更多Linq
魔法来分割结果。
答案 1 :(得分:0)
是的,这可以完成,但您应该为查询提供更好的示例。你已经在那里提供了一个糟糕的起点。让我们用这个:
SELECT value1, value2, commonValue
FROM table1
WHERE EXISTS (
SELECT 1
FROM table2
WHERE table1.commonValue = table2.commonValue
// include some more filters here on table2
)
首先,使用EXISTS代替IN几乎总是更好。
现在把它变成Lambda会是这样的,再次你没有提供任何对象或对象图,所以我只会做些什么。
DbContext myContext = this.getContext();
var myResults = myContext.DbSet<Type1>().Where(x => myContext.DbSet<Type2>().Any(y => y.commonValue == x.commonValue)).Select(x => x);
编辑 - 在您提供新的sql语句后更新
使用您的示例对象,这将产生最佳结果。同样,这比转换为IN子句的Contains更有效。
你真的想要的SQL:
SELECT *
FROM periods
WHERE EXISTS (SELECT 1 FROM ratedetails WHERE rateid = 3 AND periods.id = ratedetails.periodid)
你所追求的Lamda声明
DbContext myContext = this.getContext();
var myResults = myContext.DbSet<Periods>()
.Where(x => myContext.DbSet<RateDetails>().Any(y => y.periodid == x.id && y.rateid == 3))
.Select(x => x);
这是学习lamda以及如何使用它们的良好起点。
答案 2 :(得分:0)
这是您查询中的第二个where子句
var priodidList=ratedetails.where(x=>x.rateid ==3).DistinctBy(x=>x.rateid);
现在查询的第一部分
var selected = periods.Where(p => p.id
.Any(a => priodidList.Contains(a.periodid ))
.ToList();