Я должен был сделать это раньше, и есть два способа сделать это.
Первый - переместить все серверы в один контекст.Вы делаете это, указывая LINQ-to-SQL на один сервер, затем на этом сервере создайте связанных серверов для всех других серверов.Затем вы просто создаете представления для любых таблиц, которые вас интересуют, с других серверов, и добавляете эти представления в свой контекст.
Во-вторых, необходимо вручную выполнить объединения самостоятельно, извлекая данные из одного контекста, ииспользуя только те свойства, которые вам нужны, чтобы присоединиться к другому контексту.Например,
int[] patternIds = SessionDataProvider.Instance.ResultDataContext.Results.Select(o => o.patternId).ToArray();
var results = from p in PatternDataContext.Patterns
where patternIds.Contains(p.PatternId)
select p;
Хотя с первым легче работать, у него есть свои проблемы.Проблема заключается в том, что вы полагаетесь на то, что SQL Server обеспечивает высокую производительность при работе со связанными серверами, а это плохо известно.Например, рассмотрим этот запрос:
var results = from p in DataContext.Patterns
join r in DataContext.LinkedServerResults on p.PatternId equals r.PatternId
where r.userId = 10;
Когда вы перечислите этот запрос, произойдет следующее (давайте назовем обычный и связанный серверы MyServer
и MyLinkedServer
соответственно)
MyServer
запрашивает MyLinkedServer
о результатах MyLinkedServer
отправляет результаты обратно на MyServer
MyServer
принимает эти результаты, присоединяетсяих в таблице Patterns, и возвращает только те, у которых Results.userId = 10
Итак, теперь возникает вопрос: когда выполняется фильтрация - на MyServer
или MyLinkedServer
?По моему опыту, для такого простого запроса он обычно выполняется на MyLinkedServer
.Однако, как только запрос усложняется, вы внезапно обнаружите, что MyServer
запрашивает всю таблицу результатов из MyLinkedServer
и выполняет фильтрацию после объединения!Это приводит к бесполезной трате пропускной способности, и, если таблицы результатов достаточно велики, можно превратить запрос 50 мс в запрос 50 секунд!
Вы можете исправить несоответствующие соединения между серверами, используя хранимые процедуры, но если вы делаете многосложные межсерверные объединения, вы можете в конечном итоге написать хранимые процедуры для большинства ваших запросов, что является большой работой и в первую очередь лишает цели использовать L2SQL (не нужно писать много SQL) .
Для сравнения, следующий код всегда будет выполнять фильтрацию на сервере, содержащем таблицу результатов:
int[] patternIds = (from r in SessionDataProvider.Instance.ResultDataContext.Results
where r.userId = 10
select r.PatternId).ToArray();
var results = from p in PatternDataContext.Patterns
where patternIds.Contains(p.PatternId)
select p;
Что лучше всего подходит для вашейСитуация на ваше усмотрение.
Обратите внимание, что существует третье потенциальное решение, которое я не упомянул, так как это не совсем решение для программиста: вы можете попросить администраторов вашего сервера настроить задача репликации для копирования необходимых данных из MyLinkedServer
в MyServer
один раз в день / неделю / месяц.Это только опция, если:
- Ваша программа может работать со слегка устаревшими данными из
MyLinkedServer
- Вам нужно только читать, никогда не писать, чтобы
MyLinkedServer
- Таблицы, которые вам нужны из
MyLinkedServers
, не слишком велики - У вас есть свободное пространство / пропускная способность
- Администраторы вашей базы данных не скупы / ленивы