Использование Entity Framework 6 с несколькими схемами БД, но с использованием One DBContext

У меня есть приложение, использующее EF как ORM. В базе данных была одна схема, dbo и все работает нормально. Недавно я организовал таблицы в 4 разных схемах. Некоторые таблицы одной схемы имеют зависимости от таблиц, которые находятся на другой схеме. Все кажется действительным на стороне SQL.

На стороне приложения все взаимодействия db через EF больше не работают. Код компилируется, схемы видны в решении, сопоставления модели указывают на правильные схемы, но как только я пытаюсь вставить строку в таблицу, она не работает.

Я видел, что несколько сообщений об использовании нескольких схем потребуют использования нескольких DBC-контекстов, но я бы предпочел использовать один DBC-текст. Все мои схемы имеют один и тот же владелец dbo, и я не вижу причины использовать несколько DBC-контекстов.

Кто-нибудь знает, есть ли способ достичь этого?

Ответ 1

Вы можете сопоставить каждую таблицу с собственной схемой только с помощью плавного отображения. В подтипе DbContext вы должны переопределить OnModelCreating (если вы этого еще не сделали) и добавить такие выражения:

modelBuilder.Entity<Department>()  
    .ToTable("t_Department", "school");

Объекты, которые вы не отображаете так явно, будут помещены в схему dbo по умолчанию, или вы можете указать свой собственный

modelBuilder.HasDefaultSchema("sales");

(кратко изложено здесь)

Ответ 2

В дополнение к ответу Герта Арнольда вы также можете использовать атрибут Table в своей сущности:

using System.ComponentModel.DataAnnotations.Schema;

[Table("t_Department", Schema = "school")]
public class Department
{
    public int Id { get; set; }

    public string Name { get; set; }
}

Ответ 3

@GertArnold находится на месте с его ответом. Однако для чистой синтаксической конфеты вы также можете сделать это с помощью соглашения, чтобы вывести схему из пространства имен ваших моделей. Мы обнаружили, что это полезно для нескольких схем

modelBuilder.Types().Configure(e => {
        var schema = e.ClrType.Namespace.Split('.').Last().ToLower();
        var name = entity.ClrType.Name;
        return entity.ToTable(name, schema);
});

вышесказанное возьмет конечный компонент пространства имен и использует его в качестве имени схемы. Это позволяет избежать необходимости настройки привязки таблицы для каждого объекта.

Ответ 4

хорошо, вы положили схему o заголовок класса и т.д., но где вы определяете эту схему? например:

[Table("Test", Schema = "test1")]
public class Test
{
    public int Id { get; set; }
}

[Table("Test2", Schema = "test2")]
public class Test2
{
    public int Id { get; set; }
}

а где поставить test1 и test2? разные DbContexts или где?

Ответ 5

В моем случае это возможно, что я использую DB First для генерации моего файла EDMX, поэтому он не вызывает метод OnModelCreating.

Наконец, я удаляю все store:Schema="YourSchema" и Schema="YourSchema" в файле EDMX, и я делаю это путем записи файла bat с powershell command, как показано ниже, и выполняю bat в Projec Pre-Build Event:

powershell -Command "$varStr='store:Schema=""abcd""""'; $filePath='%~dp0SomeFolder\SomeFile.txt'; (gc $filePath) -replace $varStr, '' | Out-File $filePath"