Подтвердить что ты не робот

Как динамически сопоставить модель структуры Entity с именем таблицы

Используя подход, основанный на кодах, я хотел бы динамически сопоставить одну модель с несколькими именами таблиц. В настоящее время я могу сделать что-то вроде modelBuilder.Entity(Of Person)().MapSingleType().ToTable("Managers"), но поскольку метод OnModelCreating вызывается только один раз, я не могу сопоставить его с другими именами таблиц на лету.

В нашей текущей версии LinqToSql мы переопределяем MetaModel.GetTable() и возвращаем новый атрибут TableAttribute с нашим динамическим именем. Я не нашел такого атрибута в EF (даже если бы я не знал, как это переопределить). Поэтому мой вопрос: возможно ли это сделать (пока)?

Update

Я обнаружил, что я могу предотвратить метод OnModelCreating от кеширования отображений, вызвав

modelBuilder.CacheForContextType = false;

В результате я могу назначить определения таблиц при создании объекта. Это не совсем так, как я хотел это сделать, но он работает.

Update

О, мальчик, это была большая ошибка... Кэширование существует по какой-то причине!:) Итак, я вернусь к квадрату с сопоставлением объектов POCO. Я опубликую обновление, если выясню решение.

Финал

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

Сначала я создал отдельную библиотеку с таблицами POCO и интерфейсом

public interface IDataContext {
    System.Data.Entity.DbSet<TableGeneric> TableGeneric { get; set; }

    int SaveChanges();
}


public class TableGeneric {
    [Key]
    public int Column1 { get; set; }
    public string Column2 { get; set; }
    public DateTime Column3 { get; set; }
    public string Column4 { get; set; }
    public string Column5 { get; set; }
}

Затем, используя CSharpCodeProvider, я создал класс, который принимает следующий шаблон и превращает его в определение типа:

class DataContext : System.Data.Entity.DbContext, IDataContext {
    public System.Data.Entity.DbSet<TableGeneric> TableGeneric { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder) {
        modelBuilder
            .Entity<ContextTesting.Interfaces.EF.TableGeneric()
                .MapSingleType()
                .ToTable("$TableName$");
    }
}

С созданным типом я могу создать экземпляр, поэтому здесь мы идем

Type typeAccountants = BuildContext.CreateGenericTable("Accountants");
IDataContext context = (IDataContext)Activator.CreateInstance(typeAccountants);

Тогда остальное точно так же, как если бы у вас был нормальный DataContext. Надеюсь, это поможет кому-то еще.

4b9b3361

Ответ 1

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

Сначала я создал отдельную библиотеку с таблицами POCO и интерфейсом

public interface IDataContext {
    System.Data.Entity.DbSet<TableGeneric> TableGeneric { get; set; }

    int SaveChanges();
}


public class TableGeneric {
    [Key]
    public int Column1 { get; set; }
    public string Column2 { get; set; }
    public DateTime Column3 { get; set; }
    public string Column4 { get; set; }
    public string Column5 { get; set; }
}

Затем, используя CSharpCodeProvider, я создал класс, который принимает следующий шаблон и превращает его в определение типа:

class DataContext : System.Data.Entity.DbContext, IDataContext {
    public System.Data.Entity.DbSet<TableGeneric> TableGeneric { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder) {
        modelBuilder
            .Entity<ContextTesting.Interfaces.EF.TableGeneric()
                .MapSingleType()
                .ToTable("$TableName$");
    }
}

С созданным типом я могу создать экземпляр, поэтому здесь мы идем

Type typeAccountants = BuildContext.CreateGenericTable("Accountants");
IDataContext context = (IDataContext)Activator.CreateInstance(typeAccountants);

Тогда остальное точно так же, как если бы у вас был нормальный DataContext. Надеюсь, это поможет кому-то еще.