【问题标题】:Creating a dynamic linq query创建动态 linq 查询
【发布时间】:2011-02-18 12:37:33
【问题描述】:

我有以下疑问:

from p in dataContext.Repository<IPerson>()
     join spp1 in dataContext.Repository<ISportsPerPerson>() on p.Id equals spp1.PersonId
     join s1 in dataContext.Repository<ISports>() on spp1.SportsId equals s1.Id
     join spp2 in dataContext.Repository<ISportsPerPerson>() on p.Id equals spp2.PersonId
     join s2 in dataContext.Repository<ISports>() on spp2.SportsId equals s2.Id
     where s1.Name == "Soccer" && s2.Name == "Tennis"
     select new { p.Id };

它选择所有玩足球和网球的人。
在运行时,用户可以选择其他标签添加到查询中,例如:“曲棍球”。现在我的问题是,我怎样才能动态地将“曲棍球”添加到查询中?如果将“Hockey”添加到查询中,它将如下所示:

from p in dataContext.Repository<IPerson>()
     join spp1 in dataContext.Repository<ISportsPerPerson>() on p.Id equals spp1.PersonId
     join s1 in dataContext.Repository<ISports>() on spp1.SportsId equals s1.Id
     join spp2 in dataContext.Repository<ISportsPerPerson>() on p.Id equals spp2.PersonId
     join s2 in dataContext.Repository<ISports>() on spp2.SportsId equals s2.Id  
     join spp3 in dataContext.Repository<ISportsPerPerson>() on p.Id equals spp3.PersonId
     join s3 in dataContext.Repository<ISports>() on spp3.SportsId equals s3.Id
     where s1.Name == "Soccer" && s2.Name == "Tennis" && s3.Name == "Hockey"
     select new { p.Id };

如果查询是动态构建的,那就更好了:

private void queryTagBuilder(List<string> tags)
{
    IDataContext dataContext = new LinqToSqlContext(new L2S.DataContext());
    foreach(string tag in tags)
    {
        //Build the query?
    }
}

有人知道如何正确设置吗? 提前致谢!

【问题讨论】:

标签: c# sql linq-to-sql dynamic


【解决方案1】:

LINQ 查询在实际执行之前不会被解析。所以你可以做这样的事情:

var q = from r in ctx.records 
         /* Do other stuff */
         select r;

if (!string.IsNullOrEmpty(search)) {
  q = from r in q
       where r.title == search
       select r;
}

if (orderByName) {
  q = q.OrderBy(r => r.name);
}

/* etc */

这将创建一个正在执行的 SQL 语句。

对于您的具体问题:连接有点复杂,但我认为您可以加入其他“动态”查询。

所以你最终会得到这样的结果:

var baseQ = from p in dataContext.Repository<IPerson>()
            select p;
foreach(var tag in tags) {
   baseQ = from p in baseQ 
     join spp1 in dataContext.Repository<ISportsPerPerson>() on p.Id equals spp1.PersonId
     join s1 in dataContext.Repository<ISports>() on spp1.SportsId equals s1.Id
     where s1.name == tag
     select p;
}

/* If you have defined your relations correct, simplify to something like this.
   Does not actually work because of SportsPerPerson probably has multiple sports: */
foreach(var tag in tags) {
   baseQ = baseQ.Any(p => p.SportsPerPerson.Sports.Name == tag); 
}


var resultQ = from p in baseQ
     select new { p.Id };

【讨论】:

  • 看起来很有前途 :] 会试一试的!
【解决方案2】:

我和我的同事找到了解决方案,我们重构了查询,使其能够正常工作。我们现在使用以下查询来检索正确的结果集:

var query = dataContext.Repository<ILead>();

        foreach (var tag in tags)
        {
            String tagName = tag;
            query = query.Where(l => dataContext.Repository<ISportsPerPerson>()
                         .Any(tpl => tpl.PersonId.Equals(l.Id) && tpl.Sports.Name.Equals(tagName)));
        }
// Do something with query resultset :]

【讨论】:

    猜你喜欢
    • 2015-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-03
    • 1970-01-01
    相关资源
    最近更新 更多