LINQ将SQL实体对象作为域对象

LINQ将SQL实体对象作为域对象,linq,linq-to-sql,dns,data-access,Linq,Linq To Sql,Dns,Data Access,显然,关注点分离是我们代码中一个可取的特性,大多数人采取的第一个明显的步骤是将数据访问与表示分离。在我的情况下,LINQtoSQL在数据访问对象中用于数据访问 我的问题是,实体对象的使用应该停止在哪里?为了澄清这一点,我可以将实体对象传递到域层,但我觉得实体对象不仅仅是一个数据对象——这就像将一点DAL传递到下一层一样 假设我有一个UserDAL类,它应该在调用方法GetByID()时向域公开一个实体用户对象,还是应该抛出一个纯用于存储数据的普通数据对象?(在这种情况下,似乎是浪费性的重复) 在

显然,关注点分离是我们代码中一个可取的特性,大多数人采取的第一个明显的步骤是将数据访问与表示分离。在我的情况下,LINQtoSQL在数据访问对象中用于数据访问

我的问题是,实体对象的使用应该停止在哪里?为了澄清这一点,我可以将实体对象传递到域层,但我觉得实体对象不仅仅是一个数据对象——这就像将一点DAL传递到下一层一样

假设我有一个UserDAL类,它应该在调用方法GetByID()时向域公开一个实体用户对象,还是应该抛出一个纯用于存储数据的普通数据对象?(在这种情况下,似乎是浪费性的重复)

在这种情况下你们做了什么?有没有别的办法

希望这不是太模糊

非常感谢


Martin。

我从DAL(使用LINQ2SQL)返回POCO的IQueryable,因此没有任何Linq实体对象离开DAL。这些POCO返回到服务层和UI层,还用于将数据传递回DAL进行处理。Linq处理得非常好:

 IQueryable<MyObjects.Product> products = from p in linqDataContext.Products 
                                          select new MyObjects.Product //POCO
                                          {
                                              ProductID = p.ProductID
                                          };
 return products;
IQueryable products=来自linqDataContext.products中的p
选择新的MyObjects.Product//POCO
{
ProductID=p.ProductID
};
退货产品;

我个人不喜欢我的实体跨层分布。我的DAL返回POCO(当然,这通常意味着额外的工作,但我发现这更干净-也许在下一个.NET版本中会更简单;-)

问题并不是那么简单,对这个问题有很多不同的想法(我一直在问自己和你一样的问题)

也许你可以看看:我喜欢这个概念的本质(尤其是数据层中的映射)

希望这有帮助。

有一篇类似的帖子,但是,我看到你的问题更多的是关于你应该做什么,而不是你应该如何做

在小型应用程序中,我发现第二个POCO实现是浪费的,在大型应用程序(尤其是那些实现web服务的应用程序)中,POCO对象(通常是数据传输对象)是有用的

如果你的应用属于后一种情况,你可能想看看


希望有帮助

对于大多数项目,我们使用LINQ到SQL实体作为业务对象

LINQ to SQL设计器允许您控制其生成的类和属性的可访问性,因此您可以限制对任何允许使用者违反业务规则的内容的访问,并在部分类中提供合适的公共替代方案(尊重业务规则)

MSDN上甚至有一篇关于这种方式的文章

这样可以避免编写大量繁琐的样板代码,即使您希望从web服务返回它们,也可以这样做

是否为业务逻辑创建单独的层实际上取决于项目的大小(较大的项目通常在业务逻辑层和数据访问层之间具有较大的差异)


我相信LINQ to Entities试图通过维护两个独立的模型(一个用于业务逻辑,一个用于数据访问)为这个难题提供一站式解决方案。使用普通的LINQtoSQL,我很快放弃了DBML工具,因为它将实体紧密地绑定到DAL。我一直在努力追求更高水平的持久性,尽管微软并没有让它变得很容易

我最终做的是手工编写持久性无知层,让DAL继承我的POCO。继承的对象公开了它继承自的POCO的相同属性,因此在持久性层中,我可以使用属性映射到对象。然后,被调用的可以将继承的对象强制转换回其基类型,或者让DAL为其执行此操作。我更喜欢后一种情况,因为它减少了需要进行的铸造量。诚然,这主要是一个只读实现,因此我必须重新访问它以了解更复杂的更新场景

为此手动编码的数量相当大,因为我还必须在对象继承和映射的基础上手动维护(首先在编码之后)每个数据源的上下文和提供者。如果这个项目被否决,我肯定会转向一个更健壮的解决方案


展望实体框架,根据EF团队的设计博客,持久性忽略是一个通常要求的特性。同时,如果您决定采用EF方法,您可以随时查看预滚的持久性工具(如MSDN上的项目)来提供帮助。

我使用一个自定义的LinqToSQL生成器,它是基于我在Internet上找到的一个生成器构建的,而不是默认的MSLinqToSQLGenerator。 为了使我的上层独立于这些Linq对象,我创建接口来表示它们中的每一个,然后在这些层中使用这些接口。 例如:


当然还有很多,但这就是想法。

请记住,LINQtoSQL不是一种前瞻性的技术。它已经发布了,玩起来很有趣,但微软不会把它带到任何地方。我感觉它也不会永远被支持。看看微软的实体框架(EF),它结合了一些Linq到SQL的优点。

既然服务层(我猜)使用您的POCO,您如何处理来自服务层的更新?假设您更新了一个产品名称,如下所示:MyObjects.product=from linqDataContext.Products中的p,其中p.ID=1

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
    {
             //***
    }
}