2015-01-23 3 views
2

Im работая с EntityFramework и мне нужен какой-то метод, который будет синхронизировать входящие списки объектов с базой данных (перезаписать описание записей или пометить их как устаревшие):Generic тип T в качестве имени переменной

public void Synchronize<T>(List<T> entityList) 
    { 
     //do something 
    } 

Прежде всего мне нужно получить все данные из соответствующей таблицы и получить разницу между двумя списками (одна неизменная вещь - GUID записи). Например, если тип входящего EntityList является пользователь, то мне нужно, чтобы получить все данные из таблицы «User» и т.д.

Это не работает:

 var query = from entity in typeof(T) 
        select entity; 

Конечно, я могу сделать это старинке:

switch (typeof(T).Name) 
     { 
      case "User": 
       var query = from user in User 
          select user; 
       //Sync with User table 
       break; 
      case "Project": 
       var query = from project in Project 
          select project ; 
       //Sync with Project table 
       break; 
     } 

Но, может быть, есть элегантный способ справиться с общим? Потому что у меня есть много таблиц для синхронизации. Благодаря!

+0

Возможно, я ошибаюсь, но, похоже, вы пытаетесь заставить использовать дженерики - когда на самом деле функциональность того, что вы пишете, в любом случае зависит от типа (т. Е. Не очень общего). Вы уверены, что дженерики здесь подходят? –

+0

Вам не нужны (не должны) генераторы, когда код внутри вашего метода не является общим. –

+0

мой код может использоваться с общим, как я думаю, потому что все мои сущности, которые будут синхронизированы, выходят из ActiveDirectory, и все они включают в себя свойства Guid, Description, Name и Obsolete. Вот почему я могу попробовать использовать дженерики здесь. – Szer

ответ

5

Если у вас есть доступ к DbContext, для этого вы можете использовать способ Set<T>.

var query = from entity in context.Set<T>() select entity; 

Но чтобы заставить его работать в вашем контексте вы должны положить по крайней мере, ограничение на тип T и юридические лица должны разделять тип или интерфейс. В противном случае вы не можете создавать свои запросы, потому что T может быть чем угодно (object).

+1

Я думаю, что 'from x in y select x' может быть сокращено до' y'. – Heinzi

+1

@Heinzi, конечно. Я только хочу показать использование этого метода в контексте вопросника – Jehof

+0

Вот что мне нужно на самом деле. И, конечно же, в реальном коде это не так просто, как «from x in y select x». – Szer

2

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

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

0

Если это нормально для вас, чтобы использовать ObjectContext, вы можете сделать это следующим образом:

var octx = (ctx as IObjectContextAdapter).ObjectContext; 
var query = octx.CreateQuery<T>("SELECT VALUE v FROM " + typeof(T).Name + " AS v"); 
var result = query.ToList(); 

Смотрите больше на CreateQuery здесь: https://msdn.microsoft.com/en-us/library/bb339670(v=vs.110).aspx.

+0

Никогда не используйте '(ctx as IObjectContextAdapter)', не проверяя значения «null»! –

+0

Это полная чепуха. DbContext реализует IObjectContextAdapter, поэтому нет способа, чтобы он не работал. –

+0

Почему вы не бросаете его? –

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