2013-04-12 3 views
0

У меня есть набор параметров, которые я передаю в метод C#, который использует LINQ to SQL. Все эти параметры являются фильтрами из пользовательского интерфейса. Четыре из параметров, которые мне нужно фильтровать, находятся в одном столбце в той же таблице. Например, таблица может выглядеть следующим образом:LINQ to SQL запрос одного и того же столбца несколько раз

ID | FK_ID | Name | Value 

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

Мне нужно принять параметры фильтра и сопоставить их с колонкой Value, а также убедитесь, что имя правильно. В настоящее время я делаю это, присоединяясь к одной таблице несколько раз ... но я боюсь, что это слишком неэффективно. Каков наилучший способ сделать это? Я думаю, что я хотел бы построить запрос динамически, чтобы я мог проверить, какие фильтры установлены, но я борюсь с тем, как я должен построить свой результирующий набор. Прямо сейчас, это выглядит следующим образом: (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() 
                }; 

следует куча где заявлений и избранных. Заранее спасибо за помощь! PS извините за дерьмовое форматирование.

+0

Что вы хотите результат смотреть как? У меня возникли проблемы с визуализацией этого, основываясь на этом вопросе. –

+0

Эй, Мэтью, я обновил исходное сообщение с полным запросом, поскольку он стоит сейчас. FaultsWithFilters - это особый класс, который я создал. Достаточно ли для вас обновления, чтобы получить визуализацию набора результатов? –

+0

Итак, вы пытаетесь получить все ContextProperties для данного MessageID, где имя ContextProperties соответствует любому из «GeniusReference», «ProgramGeniusNumber», «Platform», «ModifiedBy». Звучит правильно? –

ответ

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() 
       }; 
+0

Это выглядит великолепно! И много чище! Я боюсь, что выполнение многих подключений вызовет проблему с производительностью. Таблица ContextProperties будет продолжать расти с течением времени. Выполняет ли все эти объединения все же лучший вариант? –

+0

Причина, по которой я прошу сделать все эти объединения, заключается в том, что для каждого из параметров «GeniusReference», «ProgramGeniusNumber», «Platform», «ModifiedBy» я хочу присоединиться к таблице ContextProperties, только если они установлены, в противном случае я 'd имеют ненужные соединения. –

Смежные вопросы