C# 创建动态linq查询

C# 创建动态linq查询,c#,sql,linq-to-sql,dynamic,C#,Sql,Linq To Sql,Dynamic,我有以下疑问: 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

我有以下疑问:

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 };
来自dataContext.Repository()中的p的
)
在p.Id等于spp1.PersonId的dataContext.Repository()中加入spp1
在spp1.SportsId等于s1.Id的dataContext.Repository()中加入s1
在p.Id等于spp2.PersonId的dataContext.Repository()中加入spp2
在spp2.SportsId等于s2.Id的dataContext.Repository()中加入s2
其中s1.Name==“足球”和s2.Name==“网球”
选择新的{p.Id};
它选择所有踢足球和网球的人。
在运行时,用户可以选择要添加到查询中的其他标记,例如:“Hockey”。现在我的问题是,如何在查询中动态添加“Hockey”?如果将“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 };
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 */
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 };
来自dataContext.Repository()中的p的
)
在p.Id等于spp1.PersonId的dataContext.Repository()中加入spp1
在spp1.SportsId等于s1.Id的dataContext.Repository()中加入s1
在p.Id等于spp2.PersonId的dataContext.Repository()中加入spp2
在spp2.SportsId等于s2.Id的dataContext.Repository()中加入s2
在p.Id等于spp3.PersonId的dataContext.Repository()中加入spp3
在spp3.SportsId等于s3.Id的dataContext.Repository()中加入s3
其中s1.Name==“足球”和s2.Name==“网球”和&s3.Name==“曲棍球”
选择新的{p.Id};
如果查询是动态构建的,则最好如下所示:

private void queryTagBuilder(List<string> tags)
{
    IDataContext dataContext = new LinqToSqlContext(new L2S.DataContext());
    foreach(string tag in tags)
    {
        //Build the query?
    }
}
private void queryTagBuilder(列表标记)
{
IDataContext dataContext=新的LinqToSqlContext(新的L2S.dataContext());
foreach(标记中的字符串标记)
{
//生成查询?
}
}
有人知道如何正确设置吗?
提前谢谢

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

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 };
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 */
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 };
这将创建一条正在执行的SQL语句

对于您的特定问题:连接使其变得有些复杂,但我认为您可以使用其他“动态”查询进行连接

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

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 };
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 */
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 };
var baseQ=来自dataContext.Repository()中的p
选择p;
foreach(标签中的var标签){
baseQ=从baseQ中的p开始
在p.Id等于spp1.PersonId的dataContext.Repository()中加入spp1
在spp1.SportsId等于s1.Id的dataContext.Repository()中加入s1
其中s1.name==标记
选择p;
}
/*如果您正确定义了关系,请简化为以下内容。
实际上不起作用,因为运动员个人可能有多种运动:*/
foreach(标签中的var标签){
baseQ=baseQ.Any(p=>p.SportsPerPerson.Sports.Name==tag);
}
var resultQ=来自baseQ中的p
选择新的{p.Id};

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

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 :]
var query=dataContext.Repository();
foreach(标签中的var标签)
{
字符串标记名=标记;
query=query.Where(l=>dataContext.Repository()
.Any(tpl=>tpl.PersonId.Equals(l.Id)&&tpl.Sports.Name.Equals(标记名));
}
//对查询结果集执行某些操作:]

重复?看起来很有前途:]将尝试一下!