2015-09-21 2 views
2

Я хочу, чтобы динамически поставить условие, как это: -Косвенно типизированных локальные переменные должны быть инициализированы

var data; 
if(employeId != 0) { 
data = (from a in ctx.tblTO1 
      join b in ctx.tblTO2 
        on a.Company equals b.Company 
        where a.Id == b.Id && 
        a.employeeId == employeeId 
        select new { a = a, b = b }).ToList(); 
}else{ 
    data = (from a in ctx.tblTO1 
       join b in ctx.tblTO2 
         on a.Company equals b.Company 
         where a.Id == b.Id && 
         a.Cat == cats 
         select new { a = a, b = b }).ToList(); 
} 

Результат выше выражения безымянного типа. Так что я не могу объявить его & 1-я строка дает ошибку. Implicitly typed local variables must be initialised.

Каков способ решения проблемы? Можем ли мы использовать отдельную функцию, но каковы будут типы возвращаемых функций?

+0

Вы можете уйти, объявив данные динамическими. Или просто объявите данные как список Tuple Martheen

ответ

5

Ну, конечно var data; не имеет никакого смысла.

Вы можете определить тип с соответствующими полями как тип элемента. Это особенно полезно, если один и тот же тип появляется более одного раза.

Вы также можете использовать ?: где вы здесь использовать if…else:

var data = (employeeId != 0) 
    ? (from a in ctx.tblTO1 
    join b in ctx.tblTO2 
     on a.Company equals b.Company 
     where a.Id == b.Id && 
     a.employeeId == employeeId 
     select new { a = a, b = b }).ToList() 
    : (from a in ctx.tblTO1 
    join b in ctx.tblTO2 
     on a.Company equals b.Company 
     where a.Id == b.Id && 
     a.Cat == cats 
     select new { a = a, b = b }).ToList(); 

Но, возможно, ярчайший это изменить запрос для только то, что отличается каждый случай:

var query = from a in ctx.tblTO1 
      join b in ctx.tblTO2 
      on a.Company equals b.Company 
      where a.Id == b.Id 
      select new { a = a, b = b }; 

if (employeeId != 0) 
    query = query.Where(i => i.a.employeeId == employeeId); 
else 
    query = query.Where(i => i.a.Cat == cats); 
var data = query.ToList(); 

Это имеет то преимущество, сделать разницу между двумя случаями более ясными в коде. Разделение ToList() также имеет то преимущество, что становится понятным, если вы измените свой код таким образом, чтобы его больше не нужно. :

+0

Второй блок кода выглядит хорошо. Я пойду со вторым фрагментом кода.! – Anup

+0

Да, это лучший способ. – usr

3

Вы можете использовать класс DTO вместо анонимного типа. Resharper может сделать это преобразование для вас. Или вы можете использовать условный оператор, чтобы разрешить работу типа здесь:

var data = employeId != 0 ? (query1) : (query2); 

Это не будет красиво.

Там другая хак для этого:

var data = new [] { new { a = 0, b = 0 } }.ToList(); 

Это создает фиктивный объект, чтобы сделать работу логического вывода var типа. Вы, вероятно, не следует делать это ...

0
var data = (from a in ctx.tblTO1 
       join b in ctx.tblTO2 
         on a.Company equals b.Company 
         where a.Id == b.Id && 
         ((a.Cat == cats && employeId==0)|| 
         (a.employeeId == employeeId)) 
         select new { a = a, b = b }).ToList(); 
+0

Это допустимое решение, но, вероятно, он не сможет использовать какие-либо индексы. – usr

+0

Он сможет использовать индексы. Я не вижу причин, почему это невозможно. – MikkaRin

+0

Это '||' обычно приводит к тому, что индексы не используются в SQL Server. Индекс не может использоваться для поиска двух разных столбцов. – usr

0

Вы можете переписать запрос следующим образом

(from a in ctx.tblTO1 
     join b in ctx.tblTO2 
       on a.Company equals b.Company 
       where a.Id == b.Id && 
       ((employeId != 0 && a.employeeId == employeeId) || (a.Cat == cats)) 
       select new { a = a, b = b }).ToList(); 
0

var data; не может работать, так как var только когда-либо решены против Инициализатором, а не каких-либо последующих заданий.

У вас есть два основных варианта: вы можете прекратить использование анонимных типов, или вы можете убедиться, что у вас есть инициализатор. Первый из них может выглядеть следующим образом:

class MyClass { 
    public T01 a; 
    public T02 b; 
} 

Теперь вы можете использовать List<MyClass>.

Второе из них можно разбить на два подпараметра: вы можете либо переработать существующую логику в соответствии с одним выражением, либо использовать фиктивное значение для инициализации.

Первый из них может выглядеть как var data = condition ? query1 : query2;.

Второй из них может выглядеть как var data = true ? null : query1;, где query1 никогда не оценивается, он используется только для определения типа data.

0

Вы можете не просто объявить переменную неявно, не придавая ей никакого значения. Когда вы пишете:

var a = "foo"; 

, что означает, что у вас есть переменная типа string, а не только переменную, которую вы дали значение строки. Компилятор должен знать, что такое тип в точности, даже если тип подразумевается из использования.

Когда вы пишете только объявление var a, компилятор не знает, что с ним делать. Это object? Может быть string? Число? Сколько памяти выделяется на стек?

С помощью статического текста, как C#, если вы объявите переменную, укажите тип. Вы можете сделать это следующим образом:

object data; 
// rest of your code 
0

Вместо ключевого слова var вы можете использовать ключевое слово dynamic. Вы можете найти более подробную информацию на официальном сайте MSDN ниже:

Dynamic Type C#

Некоторые фрагменты из страницы:

Visual C# 2010 вводит новый тип, динамический. Тип представляет собой статический тип , но объект типа dynamic обходит проверку статического типа. В в большинстве случаев он функционирует подобно объекту типа. Во время компиляции предполагается, что элемент , который вводится как динамический, поддерживает любую операцию.

Это альтернатива ключевому слову var. Но я думаю, что вы можете обойтись без динамики, условием в том, где предложение, как другой ответ, упомянутый на этой странице.

.Where(a=> (a.EmployeeId != 0 && a.EmployeeId == employeeId) || your other conditions) 
Смежные вопросы

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