Linq to实体-SQL查询-位置列表包含具有2个属性(或更多属性)的对象

枯木

有以下示例:

 var myIds = db.Table1.Where(x=>x.Prop2 == myFilter).Select(x=>x.Id).ToList();
 var results = db.Table2.Where(x=> myIds.Contains(x.T1)).ToList();

这部分很简单。

但是,现在我面临一个“轻微”更改,其中我的“过滤器列表”具有2个属性,而不仅仅是一个:

// NOTE: for stackoverflow simplification I use a basic query to 
// get my "myCombinationObject".
// In reality this is a much more complex case, 
// but the end result is a LIST of objects with two properties.
var myCombinationObject = db.Table3.Where(x=>x.Prop3 == myFilter)
                                   .Select(x=> new { 
                                          Id1 = x.T1, 
                                          Id2 = x.T2
                                    }).ToList();

 var myCombinationObjectId1s = myCombinationObject.Select(x=>xId1).ToList();
 var myCombinationObjectId2s = myCombinationObject.Select(x=>xId2).ToList();

 // step#1 - DB SQL part
 var resultsRaw = db.Tables.Where( x=> 
                     myCombinationObjectId1s.Contains(x.Prop1) 
                  || myCombinationObjectId2s.Contains(x.Prop2))
                .ToList();
//  step#2 - Now in memory side - where I make the final combination filter.
var resultsFiltered = resultsRaw.Where( x=>
            myCombinationObject.Contains( 
                       new {Id1 = x.Prop1, Id2 = x.Prop2 }
            ).ToList();

我的问题:是否有可能在步骤1中合并步骤2(在linq中查询实体)?

MR100

我曾经设法做过您想做的事,但是这很困难,需要稍微更改实体模型。您需要一个实体来映射类型

new {Id1 = x.Prop1, Id2 = x.Prop2 }

因此,您需要具有2个属性的实体-Id1和Id2。如果您有一个-很好,如果没有,则将这样的实体添加到模型中:

public class CombinationObjectTable
{
    public virtual Guid Id1 { get; set; }
    public virtual Guid Id2 { get; set; }
}

将其添加到模型中:

public DbSet<CombinationObjectTable> CombinationObjectTable { get; set; }

创建新的迁移并将其应用到数据库(数据库现在将具有附加表CombinationObjectTable)。之后,您开始构建查询:

DbSet<CombinationObjectTable> combinationObjectTable = context.Set<CombinationObjectTable>();
StringBuilder wholeQuery = new StringBuilder("DELETE * FROM CombinationObjectTable");
foreach(var obj in myCombinationObject)
{
    wholeQuery.Append(string.Format("INSERT INTO CombinationObjectTable(Id1, Id2) VALUES('{0}', '{1}')", obj.Id1, obj.Id2);
}
wholeQuery.Append(
    db.Tables
        .Where( x=> 
                 myCombinationObjectId1s.Contains(x.Prop1) 
              || myCombinationObjectId2s.Contains(x.Prop2))
        .Where( x=>
           combinationObjectTable.Any(ct => ct.Id1 == x.Id1 && ct.Id2 == x.Id2)
        ).ToString();
    );

 var filteredResults = context.Tables.ExecuteQuery(wholeQuery.ToString());

由于这个原因,您的主要查询保持用linq编写。如果您不想将新表添加到数据库中,这也是可以实现的。向模型添加新的类CombinationObjectTable,生成新的迁移以进行添加,然后从迁移代码中删除创建该表的代码。之后,进行迁移。这样,数据库架构不会更改,但EF会认为数据库中存在CombinationObjectTable。代替它,您将需要创建一个临时表来保存数据:

StringBuilder wholeQuery = new StringBuilder("CREATE TABLE #TempCombinationObjectTable(Id1 uniqueidentifies, Id2 uniqueidentifier);");

当您在linq查询上调用ToString方法时,将CombinationObjectTable更改为#TempCombinationObjectTable:

...
.ToString()
.Replace("CombinationObjectTable", "#TempCombinationObjectTable")

值得考虑的其他事情是使用查询参数在INSERT语句中传递值,而不是仅将它们自己包含在查询中-这当然也可以通过EF实现。该解决方案尚未完全准备好应用,而是在暗示您可能朝哪个方向发展该解决方案。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Linq查询,在哪里嵌套子对象,实体框架

来自分类Dev

在linq中查询实体的ICollection到实体

来自分类Dev

从SQL到LINQ的子查询实体框架

来自分类Dev

LINQ查询中实体的GetType

来自分类Dev

PostSharp方面:访问实体框架LINQ查询中的“注入”属性

来自分类Dev

Linq to实体子查询

来自分类Dev

使用linq传递两个参数的查询实体

来自分类Dev

linq查询实体框架如何联接表?导航属性?

来自分类Dev

从linq动态构建选择列表到实体查询

来自分类Dev

为什么实体框架linq查询的内部SQL中没有GroupBy子句?

来自分类Dev

SQL到Linq实体

来自分类Dev

嵌套查询linq到实体

来自分类Dev

Linq在实体列表上的位置

来自分类Dev

LINQ到实体动态查询

来自分类Dev

在linq中查询实体的ICollection到实体

来自分类Dev

Linq to实体查询优化

来自分类Dev

在选择的LINQ中向实体添加更多属性

来自分类Dev

从SQL到LINQ的子查询实体框架

来自分类Dev

LINQ查询中实体的GetType

来自分类Dev

具有实体和分组依据的Linq查询

来自分类Dev

LINQ(到实体)查询,带有排序和分组

来自分类Dev

通用Linq查询以获取具有指定键的实体数组

来自分类Dev

使实体框架Linq查询异步

来自分类Dev

带有实体框架查询的复杂linq

来自分类Dev

在实体查询的强类型LINQ中填充列表

来自分类Dev

选择特定实体LINQ的属性

来自分类Dev

从linq动态构建选择列表到实体查询

来自分类Dev

无法在带有实体框架的 LINQ 中使用 IN 查询

来自分类Dev

Linq SQL 将属性值设置为所选实体