LINQ To Объекты сущности SQL как объекты домена

Четкое разделение проблем является желательной чертой нашего кода и первым очевидным шагом, который большинство людей предпринимает, - это отделить доступ к данным от презентации. В моей ситуации LINQ To SQL используется в объектах доступа к данным для доступа к данным.

Мой вопрос в том, где должно останавливаться использование объекта сущности? Чтобы уточнить, я мог передать объекты сущности до уровня домена, но я чувствую, что объект сущности больше, чем просто объект данных - он как бы пропускает бит DAL до следующего слоя.

Скажем, у меня есть класс UserDAL, если он выставляет объект объекта Object в домен, когда вызывается метод GetByID(), или он должен выплевывать простой объект данных исключительно для хранения данных и не более того? (в данном случае это похоже на расточительное дублирование)

Что вы делали в этой ситуации? Есть ли альтернативный метод?

Надеюсь, что это было не слишком расплывчато.

Большое спасибо,

Martin.

Ответ 1

Я возвращаю IQueryable из POCOs из своего DAL (который использует LINQ2SQL), поэтому объект объекта Linq никогда не покидает DAL. Эти POCO возвращаются на уровень обслуживания и пользовательского интерфейса, а также используются для передачи данных обратно в DAL для обработки. Linq отлично справляется с этим:

 IQueryable<MyObjects.Product> products = from p in linqDataContext.Products 
                                          select new MyObjects.Product //POCO
                                          {
                                              ProductID = p.ProductID
                                          };
 return products;

Ответ 2

Для большинства проектов мы используем объекты LINQ to SQL как наши бизнес-объекты.

Конструктор LINQ to SQL позволяет вам контролировать доступность классов и свойств, которые он создает, поэтому вы можете ограничить доступ ко всему, что позволит потребителю нарушить бизнес-правила и предоставить подходящие общедоступные альтернативы (которые уважают бизнес правила) в частичных классах.

Там даже статья о реализует вашу бизнес-логику таким образом в MSDN.

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

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

Я полагаю, что LINQ to Entities пытается обеспечить единое решение этой проблемы, поддерживая две отдельные модели (концептуальную схему для вашего бизнес-логику и схема хранения для доступа к данным).

Ответ 3

Мне лично не нравятся мои сущности для распространения по слоям. Мой DAL возвращает POCO (конечно, это часто означает дополнительную работу, но я нашел это намного чище - возможно, это будет проще в следующей версии .NET; -)).

Вопрос не так прост, и есть много разных взглядов на предмет (я продолжаю задавать себе тот же вопрос, что и вы).

Возможно, вы можете взглянуть на Пример приложения MVC Storefront: мне нравится суть концепции (отображение, которое происходит в слой данных особенно).

Надеюсь, что это поможет.

Ответ 4

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

В небольших приложениях я считаю, что вторая реализация POCO является расточительной, в больших приложениях (особенно тех, которые реализуют веб-службы) полезен объект POCO (обычно объект передачи данных).

Если ваше приложение попадает в более поздний случай, вы можете посмотреть ADO.Net Data Services.

Надеюсь, что это поможет!

Ответ 5

Я действительно боролся с этим, также. Используя простой ванильный LINQ to SQL, я быстро отказался от инструментария DBML, потому что он привязал сущности к DAL. Я стремился к более высокому уровню упорства в невежестве, хотя Microsoft не делала это очень легко.

То, что я закончил, заключалось в том, что мы написали слой незнания персистентности, получив наследование DAL из моих POCOs. Наследуемые объекты подвергаются тем же свойствам POCO, на которые он наследуется, поэтому, находясь внутри уровня невежества персистентности, я мог использовать атрибуты для сопоставления с объектами. Вызываемый тогда может вернуть унаследованный объект обратно к его базовому типу или сделать DAL для них. Я предпочел последний случай, потому что он уменьшил количество кастингов, которые нужно было сделать. Конечно, это была прежде всего реализация только для чтения, поэтому мне пришлось бы пересмотреть ее для более сложных сценариев обновления.

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

С нетерпением ждем рамки Entity Framework, игнорирование ненадежности - это часто запрашиваемая функция в соответствии с блогами дизайна для команды EF. В то же время, если вы решите пойти по маршруту EF, вы всегда можете посмотреть на предварительно развернутый инструмент невежества настойчивости, например EFPocoAdapter проект на MSDN, чтобы помочь.

Ответ 6

Я использую собственный генератор LinqToSQL, построенный на том, который я нашел в Интернете, вместо стандартного MSLinqToSQLGenerator.  Чтобы сделать мои верхние слои независимыми от таких объектов Linq, я создаю интерфейсы для представления каждого из них, а затем использую такие интерфейсы в этих слоях. Пример:


public interface IConcept {
    long Code { get; set; }
    string Name { get; set; }
    bool IsDefault { get; set; }
}

public partial class Concept : IConcept { }

[Table(Name="dbo.Concepts")]
public partial class Concept
{
    private long _Code;
    private string _Name;
    private bool _IsDefault;
    partial void OnCreated();
    public Concept() { OnCreated(); }
    [Column(Storage="_Code", DbType="BigInt NOT NULL IDENTITY", IsPrimaryKey=true)]
    public long Code
    {
             //***
    }
    [Column(Storage="_Name", DbType="VarChar(50) NOT NULL")]
    public string Name
    {
             //***
    }
    [Column(Storage="_IsDefault", DbType="Bit NOT NULL")]
    public bool IsDefault
    {
             //***
    }
}

Конечно, есть намного больше, чем это, но эта идея.

Ответ 7

Пожалуйста, имейте в виду, что Linq to SQL не является перспективной технологией. Он был выпущен, с ним весело играть, но Microsoft ничего не предпринимает. У меня такое чувство, что оно тоже не будет поддерживаться. Взгляните на Entity Framework (EF) Microsoft, который включает в себя некоторые из преимуществ Linq to SQL.