2016-02-05 1 views
0

Je dois obtenir tous les TEntitys de mi DbContext pour extraire toutes les informations de chaque table. J'ai des petites tables avec peu d'informations. J'ai ce code mais je ne travaille pas.Comment obtenir TEntity par son nom

var dbSetPropertiesLocal = local.GetDbSetProperties();     

foreach (var item in dbSetPropertiesLocal) 
{ 
    Type type = item.PropertyType; // This need get the type of the actual TEntity 
    var enumerable = GetLocal<type>(item.Name, local); 
}     

Cette méthode renvoie toutes les données du DbSet spécifié par son nom et tE DbContext

public List<TEntity> GetLocal<TEntity>(string name, DbContext ctx) 
{ 
    var enumerable = (IEnumerable<TEntity>)(typeof([ClassNameOfMyContext]).GetProperty(name).GetValue(ctx, null)); 
    return enumerable.ToList(); 
} 

Cette méthode obtenir les propriétés de mon DbContext. J'utilise cela pour obtenir tous DbSets dans mon DbContext

public static List<PropertyInfo> GetDbSetProperties(this DbContext context) 
{ 
    var dbSetProperties = new List<PropertyInfo>(); 
    var properties = context.GetType().GetProperties(); 

    foreach (var property in properties) 
    { 
     var setType = property.PropertyType; 
     var isDbSet = setType.IsGenericType && (typeof(IDbSet<>).IsAssignableFrom(setType.GetGenericTypeDefinition()) || setType.GetInterface(typeof(IDbSet<>).FullName) != null); 

     if (isDbSet) 
      dbSetProperties.Add(property); 
    } 

    return dbSetProperties; 
} 
+0

Le but de ce code est d'obtenir toutes les données de chaque entité dans votre dbcontext? –

+0

oui, je fais un synchroniseur de base de données – Richard

+0

N'est-il pas beaucoup plus facile juste d'utiliser 'context.Set () .ToList();' À cet effet comme context.Set () .ToList() ' –

Répondre

1

Je ne sais pas si votre chemin actuel est la meilleure façon de résoudre votre problème plus (une base de données mise en œuvre synchroniseur). Mais voici une solution à votre petit problème (en appelant votre code générique). Au lieu d'une méthode d'extension, créez une classe générique et créez une instance à l'aide de la réflexion. Ajoutez également une interface pour parler à l'instance. Rappelez-vous, la classe peut être générique, mais si vous devez lui parler d'un code non générique, vous avez besoin d'une interface pour convertir une instance de classe générique en une instance d'interface non générique (si vous voyez ce que je veux dire).

public interface ILocalEntityListProvider { 
    List<object> GetLocal(string name, DbContext ctx); 
} 
public class LocalEntityListProvider<TEntity> : ILocalEntityListProvider { 
    private IEnumerable<TEntity> GetLocal(string name, DbContext ctx) 
    { 
     return (IEnumerable<TEntity>)(typeof([ClassNameOfMyContext]) 
      .GetProperty(name) 
      .GetValue(ctx, null)); 
    } 

    List<object> ILocalEntityListProvider.GetLocal(string name, DbContext ctx) { 
     return GetLocal(name, ctx) 
      .Cast<object>() 
      .ToList(); 
    } 
} 

var dbSetPropertiesLocal = local.GetDbSetProperties();     
foreach (var item in dbSetPropertiesLocal) 
{ 
    var entityType = item.PropertyType.GenericTypeArguments.First(); 
    var providerClassType = typeof(LocalEntityListProvider<>).MakeGeneric(entityType); 
    var providerInstance = Activator.CreateInstance(providerClassType) as ILocalEntityListProvider; 
    var enumerable = providerInstance.GetLocal(item.Name, local); 
} 

Note: Je n'ai pas testé cela, mais j'ai utilisé le principe plusieurs fois.

+0

"Type ne contient pas une définition pour" Make Generic "et aucune méthode d'extension qui accepte un premier argument de type" Type "trouvé" – Richard

+0

Il doit être Type.MakeGenericType. Je vais le réparer plus tard. – Maarten

+0

J'ai essayé d'utiliser votre solution et me renvoie l'erreur suivante: Vous ne pouvez pas convertir un objet de type 'System.Data.Entity.DbSet'1 [myEntity]' en type 'System.Collections.Generic.IEnumerable'1 [System .Data.Entity.DbSet'1 [myEntity]] '. – Richard