Можно ли отделить 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.