1

我有一堆参数传递给使用 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 正确。目前,我通过多次加入同一张表来做到这一点......但我担心这太低效了。最好的方法是什么?我想我想动态构建查询,这样我就可以检查设置了哪些过滤器,但我正在努力解决我应该如何构建我的结果集。现在,它看起来像:(仅供参考 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 对不起,糟糕的格式。

4

1 回答 1

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()
              };
于 2013-04-12T15:07:05.380 回答