C# 实体框架中基于某种过滤器的多实体动态连接

C# 实体框架中基于某种过滤器的多实体动态连接,c#,linq,entity-framework,C#,Linq,Entity Framework,我对实体框架和LINQ非常陌生,我有一个实体,它拥有10多个其他关联实体的一对多关系。现在,我计划在我的应用程序中创建一个搜索页面,用户可以在其中选择搜索时要考虑的字段,即10多个表 现在,我正试图编写一个查询来实现上述目标。我如何使用LINQ方法语法解决这个问题,有什么帮助吗?我的意思是,根据用户的选择编写一个多连接查询。i、 第一类、第二类。。。与主实体连接,最终将所有相关字段放在一个位置。下面是一个示例代码,实际上只是一种预感 if(somefilter#1) result = db.Co

我对实体框架和LINQ非常陌生,我有一个实体,它拥有10多个其他关联实体的一对多关系。现在,我计划在我的应用程序中创建一个搜索页面,用户可以在其中选择搜索时要考虑的字段,即10多个表

现在,我正试图编写一个查询来实现上述目标。我如何使用LINQ方法语法解决这个问题,有什么帮助吗?我的意思是,根据用户的选择编写一个多连接查询。i、 第一类、第二类。。。与主实体连接,最终将所有相关字段放在一个位置。下面是一个示例代码,实际上只是一种预感

if(somefilter#1)
result = db.Companies.Join(db.Channels, p => p.Id, k => k.CId,
                                       (p, k) => new {Company = p, Channels=k});
if(somefilter#2)
result = result.Join(db.BusinnessType, ........);

if(somefilter#3)
result = result.Join(db.Values, .......);

对于复杂的查询,使用其他LINQ表示法可能更容易。您可以像这样连接多个实体:

from myEntity in dbContext.MyEntities
join myOtherEntity in dbContext.MyOtherEntities on myEntity.Id equals myOtherEntity.MyEntityId
join oneMoreEntity in dbContext.OneMoreEntities on myEntity.Id equals oneMoreEntity.MyEntityId
select new {
    myEntity.Id,
    myEntity.Name,
    myOtherEntity.OtherProperty,
    oneMoreEntity.OneMoreProperty
}
通过添加更多join语句,可以加入其他实体。 您可以从查询中选择任何实体的属性。我提供的示例使用了一个动态类,但您也可以定义一个类似MyJoinedEntity的类,您可以在其中进行选择。要做到这一点,您可以使用以下方法:

...
select new MyJoinedEntity {
    Id = myEntity.Id,
    Name = myEntity.Name,
    OtherProperty = myOtherEntity.OtherProperty,
    OneMoreProperty = oneMoreEntity.OneMoreProperty
}
编辑:

如果希望进行条件联接,则可以使用联接所有内容所需的所有属性定义MyJoinedEntity。然后将联接分解为多个方法。像这样:

public IEnumerable<MyJoinedEntity> GetEntities() {
    var joinedEntities = from myEntity in dbContext.MyEntities
        join myOtherEntity in dbContext.MyOtherEntities on myEntity.Id equals myOtherEntity.MyEntityId
        join oneMoreEntity in dbContext.OneMoreEntities on myEntity.Id equals oneMoreEntity.MyEntityId
            select new MyJoinedEntity {
                Id = myEntity.Id,
                Name = myEntity.Name,
                OtherProperty = myOtherEntity.OtherProperty,
                OneMoreProperty = oneMoreEntity.OneMoreProperty
            };

    if (condition1) {
        joinedEntities = JoinWithRelated(joinedEntities);
    }

}

public IEnumerable<MyJoinedEntity> JoinWithRelated(IEnumerable<MyJoinedEntity> joinedEntities) {
    return from joinedEntity in joinedEntities
    join relatedEntity in dbContext.RelatedEntities on joinedEntity.Id equals relatedEntity.MyEntityId
        select new MyJoinedEntity(joinedEntity) {
            Comments = relatedEntity.Comments
        };
}

谢谢你@Daniel,但是如果我有很多if语句呢。在每个If语句中,我实际上不知道有多少以前的If都实现了,所以我不知道在selectnewpart中引入哪些字段。请你详细说明一下好吗?如果SelectedFromDropDown1应该从表1加入,如果SelectedFromDropDown2也应该从表2加入。谢谢你,丹尼尔。这是很大的帮助和工作!我只是好奇,是否有另一种方式不需要每个实体都使用方法来连接。就像一个真正的动态查询。如果您愿意,您可以将所有查询放在一个方法中,它将是一个动态查询。这些连接返回一个尚未具体化的IQueryable-查询尚未运行。在添加所有连接并调用.ToList之类的方法后,查询将运行并执行整个表达式树。谢谢@Daniel。实际上,当我尝试在方法中使用IQueryable时,我无法使用带有参数的类构造函数,例如MyJoinedEntityjoinedEntity,因为这样做会给我带来错误。相反,我使用的是IEnumerable,正如您在示例中所做的那样。从数据库性能的角度来看,这不是很糟糕吗?MyJoinedEntity是您的类。您需要为每个这样的实体自己创建一个副本构造函数。IQueryable是从数据库实体的联接中自动返回的,您不直接使用它。查看此链接以更好地了解差异: