LINQ to SQL多次查询同一列

时间:2013-04-12 14:01:45

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

我有一堆参数传递给使用LINQ to SQL的C#方法。所有这些参数都是来自UI的过滤器。我需要过滤的四个参数位于同一个表的同一列中。例如,表格可能如下所示:

ID | FK_ID | Name | Value

1 1 Param1 p1Val
2 1 Param2 p2Val
3 1 Param3 p3.Val
3 1 Param4 p4.Val

我需要获取过滤器参数并将它们与Value列匹配,并确保Name正确。目前,我通过多次加入同一个表来做到这一点......但我担心效率太低。最好的方法是什么?我想我想动态构建查询,以便我可以检查设置了哪些过滤器,但我正在努力构建我的结果集。 现在,它看起来像:( FYI ContextProperties是有问题的表)

var result = 

from f in dataContext.Faults
join m in dataContext.Messages on f.FaultID equals m.FaultID              
join c in dataContext.ContextProperties on m.MessageID equals c.MessageID
join cp in dataContext.ContextProperties on c.MessageID equals cp.MessageID
join cpp in dataContext.ContextProperties on cp.MessageID equals cpp.MessageID
join cppp in dataContext.ContextProperties on cpp.MessageID equals cppp.MessageID
where (f.DateTime >= initDate && f.DateTime <= finishDate) &&
                     f.FaultID == (faultID != Guid.Empty ? faultID : f.FaultID) &&
                     f.Application == (!string.IsNullOrEmpty(application) ? application : f.Application) &&
                     f.FaultCode == (!string.IsNullOrEmpty(faultCode) ? faultCode : f.FaultCode) &&
                     f.FailureCategory == (!string.IsNullOrEmpty(failureCategory) ? failureCategory : f.FailureCategory) &&
                     f.ErrorType == (!string.IsNullOrEmpty(errorType) ? errorType : f.ErrorType) &&
                     (f.FaultSeverity >= 0 && f.FaultSeverity <= maxFaultSeverity)
                     where (c.Value.ToString() == (!string.IsNullOrEmpty(geniusReference) ? geniusReference : c.Value.ToString())
                        && c.Name.ToString() == "GeniusReference") 
                     where (cp.Value.ToString() == (!string.IsNullOrEmpty(programNumber) ? programNumber : cp.Value.ToString())
                        && cp.Name.ToString() == "ProgramGeniusNumber")
                     where (cpp.Value.ToString() == (!string.IsNullOrEmpty(platform) ? platform : cpp.Value.ToString())
                        && cpp.Name.ToString() == "Platform")
                     where (cppp.Value.ToString() == (!string.IsNullOrEmpty(modifiedBy) ? modifiedBy : cppp.Value.ToString())
                        && cppp.Name.ToString() == "ModifiedBy")
                     select new FaultsWithFilters {
                                                    DateTime = f.DateTime
                                                    ,FaultID = f.FaultID
                                                    ,Scope = f.Scope
                                                    ,FaultCode = f.FaultCode
                                                    ,FaultSeverity = f.FaultSeverity
                                                    ,ErrorType = f.ErrorType
                                                    ,Description = f.Description
                                                    ,FaultDescription = f.FaultDescription
                                                    ,FailureCategory = f.FailureCategory
                                                    ,GeniusReference = c.Value.ToString()
                                                    ,ProgramNumber = cp.Value.ToString()
                                                    ,Platform = cpp.Value.ToString()
                                                    ,ModifiedBy = cppp.Value.ToString()
                                                    };

后面跟着一堆where语句和select。在此先感谢您的帮助! PS抱歉蹩脚的格式化。

1 个答案:

答案 0 :(得分:0)

当时创建一个查询一个子句,而不是真正看起来很糟糕的field == (filterSet ? filter : field)

首先加入所有必要的表格:

var query = dataContext.Faults.Join(dataContext.Messages, f => f.FaultID, m => mFaultID, new { f, m })
                              .Join(dataContext.ContextProperties, x => x.m.MessageID, c => c.MessageID, new { x.f, x.m, c });
                              // add all other joins here
                              // and all where conditions that are always valid

然后添加条件where条件:

if(!string.IsNullOrEmpty(geniusReference))
{
    query = query.Where(x => x.c.Value.ToString() == geniusReference);
}

// instead of:
// where (c.Value.ToString() == (!string.IsNullOrEmpty(geniusReference) ? geniusReference : c.Value.ToString())

最后添加投影:

var results = from x in query
              select new FaultsWithFilters {
                   DateTime = x.f.DateTime
                  ,FaultID = x.f.FaultID
                  ,Scope = x.f.Scope
                  ,FaultCode = x.f.FaultCode
                  ,FaultSeverity = x.f.FaultSeverity
                  ,ErrorType = x.f.ErrorType
                  ,Description = x.f.Description
                  ,FaultDescription = x.f.FaultDescription
                  ,FailureCategory = x.f.FailureCategory
                  ,GeniusReference = x.c.Value.ToString()
                  ,ProgramNumber = x.cp.Value.ToString()
                  ,Platform = x.cpp.Value.ToString()
                  ,ModifiedBy = x.cppp.Value.ToString()
              };