DRY LINQ операторы для таблиц с общими столбцами - PullRequest
2 голосов
/ 25 марта 2009

Вот интересная проблема. Есть ли способ написать некоторый код, используя LINQ to SQL, который способен выполнять таблицу UPDATE, зная только, что таблица, в которой она дается, содержит столбцы x, y, z, но не зная во время компиляции, с какой таблицей он имеет дело? *

У меня есть несколько таблиц в моей схеме БД, которые совместно используют несколько столбцов, и мне нужно применить операцию UPDATE на основе наборов, которая идентична по своей логической процедуре независимо от того, с какой из таблиц мы имеем дело.

Вот простой пример: скажем, у вас есть 3 таблицы, в которых реализована иерархия модели смежности (т. Е. Каждая строка содержит идентификатор первичного ключа и столбец идентификатора родительского идентификатора с собственной ссылкой). Каждая из таблиц также имеет логический флаг «Отключено». Когда я отключаю экземпляр какой-либо из этих сущностей, он должен каскадно проходить через дочерние элементы, т.е.

ОБНОВЛЕНИЕ MyTable SET Disabled = 1 WHERE ID = @ID или Parent_ID = @ ID

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

Ответы [ 3 ]

1 голос
/ 31 марта 2009

Классы LINQ to SQL - это обычные классы .NET, которые поддерживают интерфейс IQuery, который они переводят в SQL. (Не совсем ручная волна)

Возможно, вы сможете создать собственную реализацию IQuery и указать ее для сгенерированной реализации LINQ to SQL IQuery для соответствующей таблицы. Вы добавляете свойство с именем «TableName» и переопределяете «Где» для его поддержки.

Этот ответ может не быть полным решением, но я надеюсь, что он может указать вам правильное направление.

1 голос
/ 31 марта 2009

Просто создайте базовый класс для ваших сущностей и перенесите в него общие свойства как виртуальные свойства. Переопределите эти свойства в ваших сущностях и укажите для них атрибуты Column. Вот подробный пример .

0 голосов
/ 08 апреля 2009

Решение Али сработает (спасибо за ваш вклад), но, проведя дополнительные исследования, я предпочитаю «смешивать» с использованием интерфейсов и методов расширения.

http://msdn.microsoft.com/en-us/vcsharp/bb625996.aspx

http://mikehadlow.blogspot.com/2008/05/interface-extension-methods-mixin.html

Это имеет несколько преимуществ 1) Мне не нужно возиться с механизмом автогенерации классов LINQ в VS2008 для поддержки нового базового класса

2) Это не требует применения иерархии наследования в моих классах LINQ, я просто добавляю интерфейс к частичному объявлению класса, и внезапно все эти новые, общие функции появляются на вечеринке!

3) При необходимости я мог бы поместить методы расширения в их собственное пространство имен, а клиенты могли бы поменять их местами для других реализаций.

Комментарии, оцененные по этому подходу

...