LINQ有条件地添加加入

时间:2014-05-19 17:58:33

标签: c# linq join linq-to-entities

我有一个LINQ查询,我试图从2个表中返回数据,但我加入的表是有条件的。

这就是我想要做的事情:

if (teamType == "A"){
    var query = from foo in context.People
                join foo2 in context.PeopleExtendedInfoA
                select foo;
}
else {
    var query = from foo in context.People
                join foo2 in context.PeopleExtendedInfoB
                select foo;
}

然后我会进一步过滤查询。我显然无法通过这种方式进行设置,因为我无法访问"查询"在if块之外,但它显示了我想要做的事情。这是我稍后尝试使用查询执行的示例:

if (state != null)
{
     query = query.Where(p => p.State == state);
}

if (query != null) {
   var queryFinal = from foo in query
         select new PeopleGrid()
         {
              Name = foo.Name,
              Address = foo.Address,
              Hobby = foo2.Hobby
         }
}

我尝试返回的是来自表foo的所有数据,然后来自连接表中的一个字段,但根据逻辑,连接表将有所不同。 PeopleExtendedInfoA和PeopleExtendedInfoB都有columb' Hobby'但我无法访问' Hobby'来自连接表,这是我需要从连接表中唯一的字段。

我将如何做到这一点?

4 个答案:

答案 0 :(得分:2)

PeopleExtendedInfoAPeopleExtendedInfoB是否继承自同一个基类?您可以创建IQueryable<BaseClass>并让linq提供程序在您添加联接时为您解决。样本:

IQueryable<BasePeople> basePeople;
if (teamType == "A")
   basePeople = context.PeopleExtendedInfoA;
else
   basePeople = context.PeopleExtendedInfoB;

var query = from foo in context.People
            join foo2 in basePeople on foo.Id equals foo2.PeopleId
            select new PeopleGrid()
            {
              Name = foo.Name,
              Address = foo.Address,
              Hobby = foo2.Hobby
            };

答案 1 :(得分:0)

尝试这样:

 var queryFinal = from foo in query
                  where foo.State == state !=null ? state : foo.State
         select new PeopleGrid()
         {
              Name = foo.Name,
              Address = foo.Address,
              Hobby = foo2.Hobby
         }

答案 2 :(得分:0)

您可以查询包含相关字段的中间类型,或者如果查询足够简单,您可以使用匿名类型,如下所示。重要的是,Join调用都具有相同的返回类型({ p.Name, a.Hobby }{ p.Name, b.Hobby }都将是相同的anon类型。)

var baseQuery = context.People;

var joined = type == "A" ?
    baseQuery.Join(PeopleExtendedInfoA,
        p => p.Id,
        a => a.PeopleId,
        (p, a) => new { p, a.Hobby }) :
    baseQuery.Join(PeopleExtendedInfoB,
        p => p.Id,
        b => b.PeopleId,
        (p, b) => new { p, b.Hobby });

var result = joined.Select(x => new
    {
        x.p.Name,
        x.p.Address,
        // etc.
        x.Hobby
    };

答案 3 :(得分:0)

我明白了。感谢大家的回复,它让我的大脑再次工作,并给了我一些新的想法(即使我没有直接采取其中任何一个)我意识到我需要在最后而不是从那个方式开始加入我不必处理不同类型的过滤。这就是我所做的:

var query = from foo in context.People
            select foo;

if (state != null)
{
    query = query.Where(p => p.State == state);
}

if (query != null) {
   if (teamType == "A")
   {
      var queryFinal = from foo in query
                       join foo2 in context.PeopleExtendedInfoA
      select new PeopleGrid()
      {
          Name = foo.Name,
          Address = foo.Address,
          Hobby = foo2.Hobby
      }
   }
   else
   {
      var queryFinal = from foo in query
                       join foo2 in context.PeopleExtendedInfoB
      select new PeopleGrid()
      {
          Name = foo.Name,
          Address = foo.Address,
          Hobby = foo2.Hobby
      }
   }
}