2008-09-01 1 views
13

Теперь, когда LINQ to SQL является маленьким более зрелым, я хотел бы узнать о любых методах, которые люди используют для создания n-уровневого решения с использованием технологии, потому что для меня это не кажется очевидным.Как использовать LINQ To SQL в решении N-уровня?

ответ

1

LINQ to SQL на самом деле не имеет n-уровневой истории, которую я видел, поскольку созданные ею объекты создаются в классе вместе с остальной частью, у вас на самом деле нет сборки, которую вы может прекрасно ссылаться на что-то вроде веб-сервисов и т. д.

Единственный способ, которым я действительно считал, что использовать datacontext для извлечения данных, затем заполнить промежуточную модель данных, передать это и ссылаться на нее с обеих сторон, и используя это на вашей стороне клиента, - затем передавая их назад и выталкивая данные обратно в новый Datacontext или интуитивно обновляя строки после их восстановления.

Вот если я понять, что вы пытаетесь получить по адресу: \

Я спросил ScottGu тот же вопрос, на своем блоге, когда я первый начал смотреть на него, - но я не видел ни одного сценария или приложение в дикой природе, которое использует LINQ to SQL таким образом. Веб-сайты, такие как магазин торговой марки Rob Connery, ближе к поставщику.

1

Hm, Rockford Lhotka Печально, что LINQ to SQL - замечательная технология для сбора данных из базы данных. Он предполагает, что впоследствии они должны быть привязаны к «объектам досягаемости» (например, CSLA objetcs).

Серьезно, LINQ to SQL имеет поддержку архитектуры n-уровня, см. Метод DataContext.Update.

1

Возможно, вы захотите заглянуть в ADO .Net Entity Framework в качестве альтернативы LINQ to SQL, хотя он также поддерживает LINQ. Я полагаю, что LINQ to SQL является достаточно легким и простым, в то время как платформа Entity Framework более сложна и, вероятно, более подходит для крупных корпоративных приложений.

0

серьезно, LINQ к SQL было это поддержка многоуровневой архитектуры см метод DataContext.Update

Некоторые из того, что я прочитал предполагает, что бизнес-логика обертывания DataContext - другими словами, вы завершаете обновление так, как вы предлагаете.

Способ, которым я традиционно пишу бизнес-объекты, я обычно инкапсулирую «методы загрузки» в BO; поэтому у меня может быть метод с именем LoadEmployeesAndManagers, который возвращает список сотрудников и их непосредственных менеджеров (это надуманный пример). Возможно, это только я, но в моем интерфейсе лучше видеть e.LoadEmployeesAndManagers(), чем некоторый длинный оператор LINQ.

Во всяком случае, используя LINQ было бы, вероятно, выглядеть примерно так (не проверяется на синтаксической правильности):

var emps = from e in Employees 
       join m in Employees 
       on e.ManagerEmpID equals m.EmpID 
       select new 
          { e, 
          m.FullName 
          }; 

Теперь, если я понимаю вещи правильно, если бы это, скажем, библиотеки классов и вызывать его из мой передний конец, единственный способ, которым я могу вернуть это, - это IEnumerable, поэтому я теряю свою сильную типизированную доброту. Единственный способ вернуть строго типизированный объект - создать собственный класс Employees (плюс поле строки для имени менеджера) и заполнить его из результатов моего оператора LINQ to SQL, а затем вернуть его. Но это похоже на интуитивный счетчик ... что именно LINQ to SQL купил, если мне нужно все это сделать?

Я думаю, что я мог бы смотреть на вещи не так; любое просвещение будет оценено по достоинству.

0

«единственный способ, которым я могу вернуть это как IEnumerable, так что я теряю сильный набранное Совершенство»

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

var emps = from e in Employees 
      join m in Employees 
      on e.ManagerEmpID equals m.EmpID 
      select new Employee 
         { e, 
         m.FullName 
         }; 

Что вернет IEnumerable.

Здесь an article Я написал по этой теме.

Linq-to-sql - это ORM. Это не влияет на то, как вы разрабатываете N-многоуровневое приложение. Вы используете его так же, как и любой другой ORM.

0

@liammclennan

который будет возвращать IEnumerable. ... Linq-to-sql - это ORM. Это не влияет на то, как вы разрабатываете N-многоуровневое приложение. Вы используете его так же, как и любой другой ORM.

Тогда, я думаю, я все еще смущен. Да, Linq-to-Sql является ORM; но, насколько я могу судить, я все еще засоряю свой код переднего конца встроенными операторами типа sql (linq, а не sql .... но все же я чувствую, что это должно быть абстрагировано от переднего конца).

Предположим, что я завершаю инструкцию LINQ, которую мы использовали в качестве примера в методе. Насколько я могу сказать, единственный способ, которым я могу вернуть его этот путь:

public class EmployeesDAL 
{ 
    public IEnumerable LoadEmployeesAndManagers() 
    { 
      MyCompanyContext context = new MyCompanyContext(); 

      var emps = from e in context.Employees 
      join m in context.Employees 
      on e.ManagerEmpID equals m.EmpID 
      select new 
         { e, 
         m.FullName 
         }; 

      return emps; 
    } 

} 

С моим передним концом кода Я хотел бы сделать что-то вроде этого:

EmployeesDAL dal = new EmployeesDAL; 
var emps = dal.LoadEmployeesAndManagers(); 

Это, конечно, возвращает IEnumerable ; но я не могу использовать это, как и любой другой ORM, как вы говорите (если, конечно, я не понимаю), потому что я не могу сделать это (опять же, это надуманный пример):

txtEmployeeName.Text = emps[0].FullName 

Это то, что я имел в виду «I потерять крепкую типизированную доброту ». Я думаю, что я начинаю соглашаться с Crucible; что LINQ-to-SQL не был предназначен для использования таким образом. Опять же, если я не вижу вещи правильно, кто-то покажет мне дорогу :)

1

ОК, я собираюсь дать мне одно возможное решение.

Вставки/обновления никогда не были проблемой; вы можете объединить бизнес-логику в метод Save/Update; например

public class EmployeesDAL 
{ 
    ... 
    SaveEmployee(Employee employee) 
    { 
     //data formatting 
     employee.FirstName = employee.FirstName.Trim(); 
     employee.LastName = employee.LastName.Trim(); 

     //business rules 
     if(employee.FirstName.Length > 0 && employee.LastName.Length > 0) 
     { 
      MyCompanyContext context = new MyCompanyContext(); 

      //insert 
      if(employee.empid == 0) 
      context.Employees.InsertOnSubmit(employee); 
      else 
      { 
       //update goes here 
      } 

      context.SubmitChanges(); 


     } 
     else 
      throw new BusinessRuleException("Employees must have first and last names"); 
    } 
} 

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

public ISingleResult<GetEmployeesAndManagersResult> LoadEmployeesAndManagers() 
    { 
     MyCompanyContext context = new MyCompanyContext(); 

     var emps = context.GetEmployeesAndManagers(); 

     return emps; 
    } 
Смежные вопросы