LINQ to SQL的Web应用程序的最佳实践 [英] LINQ to SQL Web Application Best Practices

查看:168
本文介绍了LINQ to SQL的Web应用程序的最佳实践的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的经验,构建Web应用程序,我一直使用一个n层的方法。一个DAL从数据库获取数据并填充对象,BLL从DAL获取对象,并执行它们所需的任何业务逻辑,而得到它从BLL的显示数据的网站。
我最近开始学习LINQ,大部分的例子表明,从Web应用程序code-屁股(这​​是可能的,我只看到过于简化的例子)权发生的查询。在N层架构,这总是看作是一个很大的禁忌。结果
我有点不确定如何构建一个新的Web应用程序。我一直在使用服务器资源管理器和DBML设计师在VS2008创建的dbml和对象关系。这似乎有点我不清楚,如果DBML将被视为DAL层,如果网站要调用一个BLL中,然后会做LINQ查询等结果的方法
什么是一些总体架构的最佳实践,或者方法来创建使用LINQ to SQL中的Web应用程序的解决方案?

In my experience building web applications, I've always used a n-tier approach. A DAL that gets data from the db and populates the objects, and BLL that gets objects from the DAL and performs any business logic required on them, and the website that gets it's display data from the BLL. I've recently started learning LINQ, and most of the examples show the queries occurring right from the Web Application code-behinds(it's possible that I've only seen overly simplified examples). In the n-tier architectures, this was always seen as a big no-no.
I'm a bit unsure of how to architect a new Web Application. I've been using the Server Explorer and dbml designer in VS2008 to create the dbml and object relationships. It seems a little unclear to me if the dbml would be considered the DAL layer, if the website should call methods within a BLL, which then would do the LINQ queries, etc.
What are some general architecture best practices, or approaches to creating a Web Application solution using LINQ to SQL?

推荐答案

我怕你确实见过过于简化的例子。 LINQ to SQL的(System.Data.Linq程序)是你的DAL层。这些类L2S生成是​​您的域(但不与领域驱动设计混淆)。最重要的是,你还可以写你的业务层。

I'm afraid you've indeed seen overly simplified examples. LINQ to SQL (System.Data.Linq) is your DAL layer. The classes L2S generates is your domain (but not to confuse with Domain-Driven Design). On top of that you can still write your Business Layer.

我总是试图prevent泄露的LINQ to SQL 的DataContext 到presentation层(网络应用)。所以它不应该是能够创建或犯了的DataContext 。你也不应该返回的IQueryable< T> 对象到presentation层。 IMO业务层应该在的DataContext (工作单位)的寿命完全控制和SQL查询的形状。

I always try to prevent leaking the LINQ to SQL DataContext into the presentation layer (your web app). So it shouldn't be able to create or commit a DataContext. Neither should you return IQueryable<T> objects to the presentation layer. IMO the business layer should have full control over the lifetime of the DataContext (unit of work) and the shape of the SQL queries.

但是,也有几种口味。有些人帐篷放宽这些限制。甚至还有人去得多进一步。这取决于你自己的口味和应用程序的大小。该应用程序越大,就越是合理增加一些抽象层。

However, there are several flavors. Some people tent to relax these constraints. Others even go much much further. It depends on your own taste and the size of the application. The bigger the application, the more it is justified to add layers of abstraction.

不允许在的IQueryable 和离开该业务层相关的东西等数据,你最终会遇到一些有趣的挑战。例如,presentation层必须指示业务层如何排序结果。虽然你可以让presentation层的结果自行解决,这将意味着,你将不得不在presentation层,什么会导致非常糟糕执行系统从数据库获取和页面的所有数据。有几个办法解决这一问题。在所有情况下,您将需要告知业务层怎样的结果为您挑选。解决方案可以在这里找到的,所以当你搜索 LINQ动态排序。我已经写了这样的解决方案我自己,这里

When disallowing IQueryables and other data related stuff from leaving the business layer, you'll end up having some interesting challenges. For instance, the presentation layer must instruct the business layer how to sort results. While you could let the presentation layer sort the results itself, this would mean that you would have to get all data from the database and page at the presentation layer, what would lead to a very badly performing system. There are several solutions to this problem. In all cases you will need to inform the business layer how to sort the results for you. Solutions can be found here at SO when you search for LINQ dynamic sort. I've written such a solution myself, here.

这离开你的BL会带来不允许的IQueryable 是另一个挑战是,也域对象往往不能离开你的BL。大部分的LINQ to SQL的领域对象将包含延迟加载的属性(例如,收集到其他域对象)。然而,当的DataContext 是在业务层的控制,它会被处理,你将结果返回到presentation层之前。当presentation比访问延迟加载的属性,就会发生异常,因为的DataContext 已被释放。当您在业务层处置的DataContext ,这种行为当然是设计。允许$​​ P $ psentation层偷懒加载性能的手段失去BL控制发送到数据库查询,从而失去了控制性能。

Another challenge that disallowing IQueryables from leaving your BL will bring is that also domain objects can often not leave your BL. Most of your LINQ to SQL domain objects will contain lazy loaded properties (for instance, collections to other domain objects). However, when the DataContext is in control of the Business Layer, it will be disposed, before you return results to the presentation layer. When the presentation than accesses a lazy loaded property, an exception will occur, because the DataContext has already been disposed. When you dispose the DataContext in your business layer, this behavior is of course 'by design'. Allowing the presentation layer to get lazy loaded properties means the BL loses control over the queries that are sent to the database, thus losing control over performance.

要解决此问题,您应该从BL返回数据传输对象(DTO)到presentation层。一个DTO将只包含数据的没有的内部的DataContext ,并没有延迟加载特性。 DTO的可特殊格式手头的实际要求。当然铅DTO的编码开销自己,让你的系统的规模和性能需求必须证明它。为了使它更容易为我自己,我倾向于把对一个DTO静态投影方法。虽然这不符合的原则关注分离,我foudn这是一个非常实用的解。在这个CustomerDTO寻找例如:

To resolve this issue, you should return Data Transfer Objects (DTO) from the BL to the presentation layer. A DTO will contain just data and no internal DataContext, and no lazy loaded properties. A DTO can be specially formatted for the actual request at hand. DTOs of course lead to coding overhead themselves, so the size of your system and the performance needs must justify it. To make it easier for myself, I tend to put static projection methods on the a DTO. While this doesn't conform to the separation of concerns principle, I foudn it to be a very practical solution. Look for instance at this CustomerDTO:

public class CustomerDTO
{
    public int CustomerId { get; set; }
    public string Name { get; set; }
    // City is flatterned from Address.City.
    public string City { get; set; }

    internal static IQueryable<CustomerDTO> AsDTO(IQueryable<Customer> customers)
    {
        return
            from customer in customers
            select new CustomerDTO()
            {
                CustomerId = customer.Id, 
                Name = customer.Name,
                City = customer.Address.City
            };
    }
}

这DTO定义了一个内部​​ AsDTO 方法,它是能够转换客户域对象到集合收集 CustomerDTO 的DTO的。这使得域对象DTO的更容易的转换。在这个BL方法寻找例如:

This DTO defines an internal AsDTO method, which is able to convert a collection of Customer domain objects to a collection of CustomerDTO DTOs. This makes conversion of domain objects to DTOs much easier. Look for instance at this BL method:

public static CustomerDTO[] GetCustomersByCountry(string country)
{
    using (var db = ContextFactory.CreateContext())
    {
        IQueryable<Customer> customers =
            (from customer in db.Customers
            where customer.Address.Country == country
            orderby customer.Name, customer.Id);

        return CustomerDTO.AsDTO(customers).ToArray();
    }
}

这个方法的好处是,当你在SQL查询,你会看到只有客户ID,名称和城市的地址表从数据库中检索。这是因为 AsDTO 方法转换有一个的IQueryable 到另一个,让LINQ to SQL来在数据库中执行的总操作

The nice thing about this approach is that when you look at the SQL query, you'll see that only the customer Id, Name and the City of the Address table will be retrieved from the database. This is because the AsDTO method translates one IQueryable to another, allowing LINQ to SQL to perform the total operation in the database.

我希望这给你能做什么了。当然,这是我对这个问题和事物的看法,我在我的情况下发现实际的。

I hope this gives some ideas of what you can do. Of course, this is my view on the subject and the things I've found practical in my situations.

这篇关于LINQ to SQL的Web应用程序的最佳实践的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆