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

Создание модели структуры Entity охватывает несколько баз данных

Можно ли сделать что-то вроде

CREATE SYNONYM [dbo].[MyTable] FOR [AnotherDatabase].dbo.[MyTable]

а затем изменить файл Entm Framework edmx, чтобы прочитать этот объект, как и любая другая таблица?

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

Я получаю определение таблицы, создавая файл edmx, указывающий на вторую базу данных, создавая там сущности, затем копируя/вставляя определение в первый файл edmx базы данных.

ОБНОВЛЕНИЕ

Если кому-то интересно, я написал, что сделал, чтобы создать промежуточные массивы edmx mulitple здесь. Он включает скрипты для генерации синонимов и объединения файлов edmx.

4b9b3361

Ответ 1

Если вы сделали тест, и это сработало, вы, вероятно, показали что-то, о чем никто больше не знает. До сих пор я всегда отвечал на этот вопрос: невозможно использовать единую модель с двумя базами данных (с более уродливым обходным путем, основанным на представлениях, скрывающих таблицы из второй базы данных). Теперь я знаю два обхода.

Единственным недостатком такого подхода является то, что все изменения, внесенные вручную в часть SSDL вашего EDMX, всегда теряются, если вы запускаете модель обновления из базы данных. Это означает либо ручную разработку EDMX (это довольно тяжелая работа), либо использование некоторого инструмента / script, который добавит ваши изменения после каждого обновления из базы данных.

Ответ 2

Вы также можете сделать это с помощью представлений (и связанного сервера, если другой db находится на другом сервере). Это не позволит вам управлять/объединять два отдельных файла edmx. Я использовал это со связанным сервером для чтения данных со второго db на другом сервере, но провел несколько быстрых тестов, чтобы увидеть, возможно ли обновление/вставки/удаления, и они есть.

У меня нет опыта работы с распределенными транзакциями, поэтому информация, связанная с распределенными транзакциями, может быть хорошей, плохой или немного. Если ваши два db находятся на одном сервере, я ASSUME больше не применяются.

Есть несколько вещей, которые следует иметь в виду при использовании связанного сервера.

  • При изменении объектов в связанных таблицах db и вызове SaveChanges в вашем контексте это попытается запустить распределенную транзакцию, поэтому, если кто-либо не знает, как остановить это, вам нужно убедиться, что два сервера настроены на обрабатывать распределенные транзакции. (Я бы предположил, что это будет верно и с использованием синонимов).
  • Вставки для объектов с столбцами идентификации на связанном сервере вызывают исключение, потому что ef пытается получить новый идентификатор с помощью SCOPE_IDENTITY(), и он равен нулю. Я не знаю, есть ли способ обойти это. У меня не было никаких проблем с обновлением или удалением объектов на связанном сервере с столбцами идентификации.

В SQL Server A

  • создать связанный сервер с ServerB (пропустите это, если db находятся на одном сервере).
  • создать представление в [ServerA].[MyDB] для каждой таблицы в [ServerB].[AnotherDB], к которой вы хотите получить доступ

В EDMX

  • Добавьте свои представления в файл edmx
  • Очистить настройку ключа сущности от каждого свойства в конструкторе (включая фактический pk)
  • Reset ключ сущности для фактического pk
  • Добавить ассоциации по мере необходимости
  • Сохранить изменения

Для обновлений/вложений/удалений

  • щелкните правой кнопкой мыши на вашем файле edmx и откройте редактор xml.
  • Перейдите к StorageModelSchemaEntityContainer
  • Найдите объект сущности для объекта и удалите элемент DefiningQuery
  • Найдите атрибут store:Schema в наборе сущностей и удалите store:, чтобы он был просто Schema. Оставьте свое значение в покое.
  • Повторите шаги 3 и 4 для каждого вида со связанного сервера.
  • Сохранить изменения

Поскольку использование связанного сервера создает распределенную транзакцию, мне пришлось сделать пару вещей на ObjectContext до того, как SaveChanges был успешным.

ctx.Connection.Open();
ctx.ExecuteStoreCommand("set xact_abort on");
ctx.SaveChanges();
ctx.Connection.Close();

Возможно, вы можете создать пользовательский ObjectContext и переопределить SaveChanges, чтобы добавить этот материал.

Ответ 3

Я обнаружил, что этот трюк с синонимами работает отлично с помощью подхода "Первый код" без каких-либо манипуляций с файлами edmx!

Единственное, что вам нужно сделать, это "привязать" ваш класс к соответствующему синониму в методе OnModelCreating вашего DataContext.

Например,, если у меня есть синоним таблицы Персонал в другом БД (а также имя класса - это Персонал), а синонимное имя "myschema.MySynonym" , тогда метод OnModelCreating должен выглядеть так:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.HasDefaultSchema("myschema");

        modelBuilder.Entity<Personnel>()
            .ToTable("MySynonym");

        Database.SetInitializer<TestSynonymContext>(null);

        base.OnModelCreating(modelBuilder);
    }