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(标记名));
}
//对查询结果集执行某些操作:]
重复?看起来很有前途:]将尝试一下!