2015-10-02 3 views
0

У меня проблема, я полностью застрял в том, что делать. Я новичок в EF :(генерируемый объект генерирует «Тип объекта не является частью модели для текущего контекста». Код перекомпиляции

Я использовал code от Adriaan Booysen для создания динамической модели. Я не могу использовать WCFDataService из-за ограничений, и я изменил часть кода, чтобы сделать это работайте для меня. Когда я запускаю его в первый раз, он работает, я получаю свои данные, но когда я снова выполняю метод, я получаю ошибку, что тип объекта не является частью модели.

Что я «Я заметил, что когда я запускаю приложение и создаю первую Entity, OnModelCreating запускается, и модель добавляется, но во второй раз это не происходит, и я думаю, именно поэтому я получаю ошибку, но я Не знаю, что делать, чтобы снова загорелся.

Это код DynamicDbContext

public partial class DynamicDbContext : DbContext 
{ 
    public DynamicDbContext() 
     : base("name=DynamicDbContext") 
    { 
     Database.SetInitializer(new NullDatabaseInitializer<DynamicDbContext>()); 
    } 

    public void AddTable(Type type, List<string> KeyFields) 
    { 
     _tables.Add(type.Name, type); 
     _keys = KeyFields; 
    } 

    private List<string> _keys; 
    private Dictionary<string, Type> _tables = new Dictionary<string, Type>(); 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     //base.OnModelCreating(modelBuilder); 
     var entityMethod = modelBuilder.GetType().GetMethod("Entity"); 

     foreach (var table in _tables) 
     { 
      entityMethod.MakeGenericMethod(table.Value).Invoke(modelBuilder, new object[] { }); 
      foreach (var pi in (table.Value).GetProperties()) 
      { 
       if (_keys.Contains(pi.Name.ToUpper())) 
        modelBuilder.Entity(table.Value).HasKey(pi.PropertyType, pi.Name); 
       else 
        switch (pi.PropertyType.Name) 
        { 
         case "Int16": 
         case "Int32": 
         case "Int64": 
         case "Boolean": 
          modelBuilder.Entity(table.Value).PrimitiveProperty(pi.PropertyType, pi.Name); 
          break; 
         default: 
          modelBuilder.Entity(table.Value).DynamicProperty(pi.PropertyType, pi.Name); 
          break; 
        } 
      } 
     } 
    } 
} 

У меня есть класс, то, чтобы получить DbSet

public class Class1 : DynamicDbContext 
{ 

    public DbSet LoadTypes(string TableName, Dictionary<string, Type> Fields, List<string> KeyFields) 
    { 
     var dcf = new DynamicClassFactory("Query." + TableName); 
     var type = CreateType(dcf, TableName, Fields); 

     AddTable(type, KeyFields); 
     return Set(type); 
    } 

    private static Type CreateType(DynamicClassFactory dcf, string name, Dictionary<string, Type> Fields) 
    { 
     var type = dcf.CreateDynamicType<BaseDynamicEntity>(name, Fields); 
     return type; 
    } 
} 

DynamicClassFactory создает в сборе памяти. Если вы посмотрите на код кодекса, вы можете увидеть, что он делает. Я ничего там не менял.

В моем приложении я делаю следующее:

var c = new Class1(); 
var Types = new Dictionary<string, Type>(); 
/*Code to populate the Fields and Field Types into the Types variable*/ 
source.QueryableSource = c.LoadTypes(TableName, Types, new List<string>() { "NO" }); 

источником является EntityServerModeSource от DevExpress и позволяет мне более эффективно заполнить стержень. Если кто-нибудь может просто указать мне в правильном направлении, что делать, я могу понять это, но в настоящее время я не уверен, что делать.

ответ

0

Я получил его для работы с помощью компиляции модели. Поскольку я не создаю базу данных или не делаю никаких обновлений, вставляет или удаляет в модели, но просто использую ее для извлечения данных из таблицы или таблиц, я переместил код из OnModelCreating в статический метод в свой класс DbContext и позвонил это из конструктора, который компилирует модель при открытии запроса. Вот код

public DynamicDbContext(string connString, Type type, List<string> KeyFields) 
    : base(GetConnection(connString), GenerateDbCompiledModel(connString, type, KeyFields), true) 
{ 
    Database.SetInitializer(new NullDatabaseInitializer<DynamicDbContext>()); 
} 

private static DbConnection GetConnection(string connectionString) 
{ 
    var factory = DbProviderFactories.GetFactory("Oracle.ManagedDataAccess.Client"); 
    var conn = factory.CreateConnection(); 
    conn.ConnectionString = connectionString; 
    return conn; 
} 

public static DbCompiledModel GenerateDbCompiledModel(string connectionString, Type entityType, List<string> _keys) 
{ 
    string tableName = entityType.Name; 
    string schema = entityType.FullName.Replace("Dynamic.Objects.", "").Replace("." + tableName, ""); 

    _keys = _keys.Select(x => 
    { 
     x = x.ToUpper(); 
     return x; 
    }).ToList(); 

    tableName = entityType.Name; 
    DbModelBuilder dbModelBuilder = new DbModelBuilder(DbModelBuilderVersion.Latest); 
    var entityMethod = dbModelBuilder.GetType().GetMethod("Entity"); 
    dbModelBuilder.HasDefaultSchema(schema); 
    entityMethod.MakeGenericMethod(entityType).Invoke(dbModelBuilder, new object[] { }); 
    foreach (var pi in (entityType).GetProperties()) 
    { 
     if (_keys.Contains(pi.Name.ToUpper())) 
      dbModelBuilder.Entity(entityType).HasKey(pi.PropertyType, pi.Name); 
     else 
      switch (pi.PropertyType.Name) 
      { 
       case "Int16": 
       case "Int32": 
       case "Int64": 
       case "Boolean": 
        dbModelBuilder.Entity(entityType).PrimitiveProperty(pi.PropertyType, pi.Name); 
        break; 
       default: 
        dbModelBuilder.Entity(entityType).DynamicProperty(pi.PropertyType, pi.Name); 
        break; 
      } 
    } 
    var factory = DbProviderFactories.GetFactory("Oracle.ManagedDataAccess.Client"); // Oracle.ManagedDataAccess.Client"); 
    var conn = factory.CreateConnection(); 
    conn.ConnectionString = connectionString; 

    return dbModelBuilder.Build(conn).Compile(); 
} 

Причина, по которой у меня есть GetConnection потому, что приложение использует DevArt, а также, и по какой-то причине new OracleConnection используется либо один, который дал мне еще одно сообщение об ошибке.

My Entity включены схемы и TABLENAME как часть полного имени, поэтому я могу извлечь схему из entityType.FullName

Я надеюсь, что это помогает кому-то, что также хочет создать Entity модели на лету для отображения цели.

-1

Проблема возникает, когда ваша строка подключения неверна. проверьте имя провайдера и, вероятно, материал EF

+0

Я не уверен, прочитаете ли вы мой вопрос? Итак, как вы пришли к выводу, что строка соединения в противном случае была бы правильной, если бы я сказал, что она работает в первый раз, а во второй раз она дает ошибку? Когда поставщик неверен, он все равно дает общую ошибку. Извините, если я немного разозлился, но я дал много информации о проблеме, и ваш ответ действительно не очень полезен – Jaques