2015-08-02 5 views
1

Исходя из [разницы между Type.IsGenericType и Type.IsGenericTypeDefinition] [1], я получил часть информации, которую мне не хватало, чтобы иметь возможность извлеките DbSets DbContext через Reflection.Зацикливание на производные DbContext DbSets, поэтому я могу добавить расширение ClearAll() к моему объекту DbContext

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

dbSet является реальным экземпляром одного из DbSets < ...> из моего DbContext, но как передать его в определение своего реального типа? (Возьмите 1 итерации цикла, dBSet будет представлять DbSet - как обеспечить этот тип во время компиляции на этой переменной


Update: Я только что рассмотрели, что я пытаюсь сделать, и ... я? боюсь, что это не имеет смысла/это невозможно. Поскольку реальные типы обнаруживаются только во время выполнения, я не могу до этого (и время компиляции - это этап времени до этого) относятся к реальным общим типам

В любом случае - мне очень интересно, что во время компиляции IDE показывает мне членов IEnumerable<T> (DbSet <) реализует его). ed, чтобы передать его DbSet<>. Как должен выглядеть такой актерский состав?

Возможно ли это?!

private static void Main(string[] args) 
{ 
    MyDb myDb = new MyDb(); 

    List<PropertyInfo> dbSetProperties = myDb 
     .GetType() 
     .GetProperties() 
     .Where(pi => pi.PropertyType.IsGenericType && string.Equals(pi.PropertyType.GetGenericTypeDefinition().FullName, typeof(DbSet<>).FullName, StringComparison.OrdinalIgnoreCase)).ToList(); 

    foreach (PropertyInfo dbSetProperty in dbSetProperties) 
    { 
     Type[] typeArguments = dbSetProperty.PropertyType.GetGenericArguments(); 
     Type dbSetGenericContainer = typeof(DbSet<>); 
     Type dbSetGenericType = dbSetGenericContainer.MakeGenericType(typeArguments); 
     object dbSet = Convert.ChangeType(dbSetProperty.GetValue(myDb), dbSetGenericType); 
    } 
} 

public class MyDb : DbContext 
{ 
    public DbSet<A> A { get; set; } 
    public DbSet<B> B { get; set; } 

    public void ClearTables() 
    { 
    } 
} 

public class A 
{ 
    public string aaa { get; set; } 
    public List<int> myList { get; set; } 
} 

public class B 
{ 
    public int MyInt { get; set; } 
} 
+1

Использование 'pi.PropertyType.IsGenericType' –

+0

@UlugbekUmirov: вы правы ... Мне сейчас интересно, как парень в другом посте получает свои результаты ... – Veverke

+0

@Veverke: Спасибо, что нашли эту ошибку. В моем ответе он был исправлен [dasblinkenlight] (http://stackoverflow.com/users/335858/dasblinkenlight) тем временем! –

ответ

1

DbSet<> сам по себе не является типом; ваш вопрос на самом деле не имеет смысла.

Однако, к счастью для вас, DbSet<T> реализует базовый класс базовых классов DbSet, поэтому вы можете использовать его вместо этого.

+0

Я могу сделать DbSet dbSet = Convert.ChangeType (dbSetProperty.GetValue (myDb), dbSetGenericType) как DbSet; но то, что я действительно хочу, - это способ удалить все элементы каждого DbSet, я хотел добавить функциональность ClearAll в DbContext. Я не вижу, чтобы DbSet предоставлял мне все, что могло бы помочь мне в этом. Я пытаюсь сделать DbSet AsQueryable, но я не вижу, как это может мне помочь. Мне нужно что-то вроде AsEnumerable() – Veverke

+0

@Veverke: 'Convert.ChangeType' совершенно бесполезен для вас; это не имеет ничего общего с этой ситуацией. Вместо этого вы можете сделать общий метод, который принимает 'DbSet ' и использовать Reflection для вызова его с правильным' T'. – SLaks

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