11

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

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

假设我有一个 UserDAL 类,它应该在调用 GetByID() 方法时将实体 User 对象暴露给域,还是应该吐出一个纯数据对象,纯粹用于存储数据,仅此而已?(在这种情况下似乎是浪费的重复)

在同样的情况下,你们做了什么?有替代方法吗?

希望这不是太模糊。

非常感谢,

马丁。

4

7 回答 7

5

我从我的 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;
于 2008-11-18T15:12:00.200 回答
3

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

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

MSDN上甚至还有一篇关于以这种方式实现业务逻辑的文章。

这使您免于编写大量繁琐的样板代码,如果您想从 Web 服务返回它们,您甚至可以使您的实体可序列化。

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

我相信 LINQ to Entities 试图通过维护两个独立的模型(业务逻辑的概念架构和数据访问的存储架构)来为这个难题提供一站式解决方案。

于 2008-11-24T14:58:13.203 回答
1

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

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

也许您可以看一下MVC Storefront 示例应用程序:我喜欢这个概念的本质(尤其是在数据层中发生的映射)。

希望这可以帮助。

于 2008-11-18T15:13:38.353 回答
1

这里有一个类似的帖子,但是,我看到你的问题更多的是关于你应该做什么,而不是你应该怎么做。

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

如果您的应用属于后一种情况,您可能需要查看ADO.Net Data Services

希望有帮助!

于 2008-11-18T15:16:20.767 回答
0

实际上,我也为此苦苦挣扎。使用普通的 LINQ to SQL,我很快放弃了 DBML 工具,因为它将实体紧密地绑定到 DAL。我一直在争取更高水平的持久性无知,尽管微软并没有让它变得很容易。

我最终做的是通过让 DAL 从我的 POCO 继承来手写持久性无知层。继承的对象暴露了它继承的 POCO 的相同属性,因此在持久性无知层内,我可以使用属性映射到对象。然后被调用者可以将继承的对象转换回其基本类型,或者让 DAL 为它们执行此操作。我更喜欢后一种情况,因为它减少了需要完成的铸造量。诚然,这主要是只读实现,因此我将不得不重新访问它以应对更复杂的更新场景。

为此手动编码的数量相当大,因为除了对象继承和映射之外,我还必须手动维护(在编码之后,开始)每个数据源的上下文和提供程序。如果该项目被弃用,我肯定会转向更强大的解决方案。

期待 Entity Framework,根据 EF 团队的设计博客,持久性无知是一个普遍要求的功能。同时,如果您决定走 EF 路线,您可以随时查看预先推出的持久性无知工具(例如 MSDN 上的EFPocoAdapter项目)来提供帮助。

于 2008-11-24T15:10:33.320 回答
0

我使用了一个基于我在 Internet 上找到的自定义 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
    {
             //***
    }
}

当然还有更多的东西,但这就是想法。

于 2008-11-26T19:42:38.107 回答
0

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

于 2008-11-26T19:50:12.520 回答