实体框架(使用In和Select Distinct)

时间:2015-09-02 15:14:04

标签: c# entity-framework

我对Entity Framework 6.0相对较新,我遇到过一种情况,我想在我的C#app中执行一个类似于这个SQL查询的查询:

select * from periods where id in (select distinct periodid from ratedetails where rateid = 3)

实际上是否可以在EF中执行这样的查询,还是需要将其分解为更小的步骤?

3 个答案:

答案 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以及如何使用它们的良好起点。

Lambda Expressions (C# Programming Guide)

答案 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();