Можно ли отделить LINQ to SQL от объектов?
Мне нравится LINQ to SQL, но кажется, что классы, которые он создает, тесно связаны с базой данных, в которой они хранятся, что похоже на Bad Thing.
Например, используя базу данных olde Northwind, если я создаю dbml с таблицей Products, генерируется класс Product
. Я могу использовать этот класс в любом другом уровне, который все хорошо и хорошо, но если я решаю, что лучше использовать простой старый ADO.NET(или базы данных коммутаторов), мне придется воссоздать класс Product
, с любой другой "моделью".
Есть ли способ обойти это? Или создать свои объектные модели отдельно, а затем отобразить на них таблицы? Я играл с различными классами отображения, но пока не нашел удовлетворительного ответа.
Ответы
Ответ 1
Все эти ответы и ссылки отсутствуют! Может быть, я могу помочь:
Атрибуты, о которых говорилось выше
Частичный класс, о котором говорил Маркус Кинг
Я несколько раз измучился из-за этой трудности, что в конце моего последнего проекта заключался в использовании интерфейсов в качестве контракта, который был разделен между всеми различными проектами в решении, а частичные классы реализовали его.
[Table(Name="Products")]
public partial class Product: IProduct { }
И да, к сожалению, для реализации POCO потребовалась некоторая магия отражения.
В конце концов, если вы действительно обеспокоены этим, я бы пошел с NHibernate (мне тоже это не нравится), что делает именно то, что, по-видимому, описывает Гарри Шултер.
Надеюсь, что это поможет!
Ответ 2
Моя команда недавно сражалась с этой проблемой. Я действительно хотел сохранить "постоянство невежества", что означает, что объекты домена могут быть созданы как простые старые объекты С#, не будучи принужденными наследовать от определенного базового класса или загромождать класс с кучей атрибутов. Как вы сказали, мы хотели иметь возможность изменять уровень персистентности независимо от бизнес-модели.
В конце концов, мы решили, что LINQ - это не путь, если вы хотите сохранить незнание. В итоге мы создаем слишком много кода для преобразования между слоем LINQ и нашим бизнес-слоем. Когда мы начали писать кучу кода на основе отражения, чтобы попытаться сделать эти сопоставления автоматически, мы поняли, что мы сползаем вниз по кроличьей дыре, и мало что можем показать для нее.
Если для вас важно незнание персистенции, вам может быть лучше подан с полноценным ORM, например NHIbernate.
Ответ 3
Linq to SQL (или EF) не относится к сохранению-незнанию. Речь идет об объектном представлении данных.
NHibernate - это ORM ненасилия, который вы можете искать.
Ответ 4
Недавно я достиг этого, создав POCOs самостоятельно и вручную создав файл сопоставления XML для базы данных. Это требует немного ручного труда, но оно дает желаемый эффект.
Здесь сообщение в блоге, которое я нашел полезным, чтобы вы начали.
Ответ 5
О, эй, думаю, я нашел решение для этого, наблюдая Rob Conery screencasts на ASP.NET MVC. Трюк заключается в select
в объект в вашем запросе LINQ to SQL.
public IQueryable<LinqExample.Core.Person> GetAll() {
var people = from pe in this.db.Persons
select new Person {
Id = pe.id,
FirstName = pe.fname,
LastName = pe.lname,
Reports = this.GetReports(pe.id)
};
return people;
}
Это позволит вам определить класс Person
в другом месте вашего кода. Я написал об этом более подробно.
Ответ 6
Скотт Гензельман сделал экран, рассказывающий об asp.net DynamicData, где он использовал классы Linq To Sql. Хотя он не рассматривал конкретный вопрос, я думаю, что общая концепция все равно будет работать. Его подход заключался в создании отдельного частичного класса с тем же именем, что и класс Product
в вашем случае, который был сгенерирован dbml. Тогда вы всегда должны иметь класс Product
, который существует вне того, что LINQ генерирует и просто "расширяет", что он делает.
Ответ 7
Просто скопируйте сгенерированный код в свои собственные классы и отключите генерацию кода. Магия в атрибутах не что иное.
В качестве альтернативы вы можете написать свои собственные объекты CLR без атрибутов и использовать внешний файл сопоставления XML для описания взаимосвязи между объектами и базой данных. Более подробную информацию можно найти в документации LINQ to SQL на MSDN.