代码之家  ›  专栏  ›  技术社区  ›  Giovanni Galbo

如何在n层解决方案中使用Linq to SQL?

  •  15
  • Giovanni Galbo  · 技术社区  · 16 年前

    现在Linq to SQL是 小的 更成熟的是,我想知道人们正在使用任何技术来使用该技术创建一个n层的解决方案,因为它对我来说并不那么明显。

    7 回复  |  直到 16 年前
        1
  •  1
  •   crucible    16 年前

    我看到的Linq-to-SQL并没有真正的N层故事,因为它创建的对象是在类中创建的,而其他对象都是在类中创建的,所以您实际上没有可以通过Web服务等方式很好地引用的程序集。

    我真正考虑的唯一方法是使用DataContext获取数据,然后填充一个中间数据模型,通过它并在两侧引用它,然后在客户端使用它-然后将它们传回并将数据推回到一个新的DataContext中,或者在您重新蚀刻行后智能地更新行。

    如果我能理解你的意图:\

    当我第一次开始查看时,我在他的博客上问了斯科特古同样的问题——但我在野外没有看到过一个场景或应用程序以这种方式使用LinqToSQL。像RobConnery的店面这样的网站更接近提供商。

        2
  •  1
  •   Brandon    16 年前

    嗯, Rockford Lhotka 遗憾的是,linq-to-sql是从数据库中获取数据的极好技术。他建议以后必须将它们绑定到“到达域对象”(又名。CSLA ObjETCS)

    说真的,Linq to SQL支持N层架构,请参见 数据上下文.更新 方法。

        3
  •  1
  •   tbreffni    16 年前

    你可能想看看 ADO .Net Entity Framework 作为LINQ到SQL的替代方案,尽管它也支持LINQ。我相信LinqToSQL的设计是相当轻量和简单的,而实体框架更重,可能更适合大型企业应用程序。

        4
  •  1
  •   Giovanni Galbo    16 年前

    好吧,我给自己一个可能的解决办法。

    插入/更新从来都不是问题;您可以用保存/更新方法包装业务逻辑;例如

    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;
        }
    
        5
  •  0
  •   Giovanni Galbo    16 年前

    说真的,linq to sql支持n层体系结构,请参阅dataContext.update方法

    我读到的一些内容表明业务逻辑包装了数据上下文——换句话说,您按照您建议的方式包装了更新。

    传统上,我编写业务对象的方式通常也将“加载方法”封装在BO中;因此,我可能有一个名为LoadEmployeesAndManagers的方法,它返回员工及其直接经理的列表(这是一个人为的示例)。也许只是我一个人,但在我的前端,我宁愿看到e.loadeEmployeesandManagers()而不是一些长的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究竟买了我什么?

    我想我可能看错了东西,任何启蒙都会被感激的。

        6
  •  0
  •   liammclennan    16 年前

    “我唯一可以返回的方法是作为一个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的方式相同。

        7
  •  0
  •   Giovanni Galbo    16 年前

    @利姆克伦南

    它将返回IEnumerable。…linq to sql是一个ORM。它不会影响您设计n层应用程序的方式。您使用它的方式与使用任何其他ORM的方式相同。

    我想我还是很困惑。是的,LinqToSQL是一个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;但是我不能像您所说的任何其他形式那样使用它(当然,除非我误解了),因为我不能这样做(再一次,这是一个人为的例子):

    txtEmployeeName.Text = emps[0].FullName
    

    这就是我所说的“我失去了强类型的优点”,我认为我开始同意Crucible的观点;Linq-to-SQL并没有被设计成这样使用。再说一次,如果我看得不正确,有人给我指路:)