Linq to Sql和分离关注 - 我这样做对吗?

时间:2013-12-06 23:50:06

标签: c# linq-to-sql separation-of-concerns

我正在开发一个项目,我正在使用LINQ to SQL,并且已经设置了要在我的Web应用程序中使用的业务对象/模型。我正在寻找一些关于我如何设置这一切的反馈,以确定它是否有意义,以及是否有任何我应该做的不同。

这是一个示例模型:

public class User
{
    private MyDataContext _db = new MyDataContext();
    private MyLINQUserClass _user = new MyLINQUserClass();

    public string Name
    {
        get
        {
             return _user.Name;
        }
        set
        {
             _user.Name = value;
        }
    }

    public User(int UserID)
    {
        _user = _db.Where(u => u.UserID == UserID).FirstOrDefault();
        if (_user == null)
        {
            _user = new MyLINQUserClass();
        }
    }

    internal User(MyLINQUserClass user, MyDataContext db)
    {
        _db = db;
        _user = user;
    }

    public void Save()
    {
        _db.SubmitChanges();
    }

    public static User Add(string Name)
    {
        MyDataContext _db = new MyDataContext();
        MyLINQUserClass _user = new MyLINQUserClass();

        _user.Name = Name;
        _db.MyLINQUserTable.InsertOnSubmit(_user);
        _db.SubmitChanges();

        return new User(_user, _db);
    }

    public static IList<User> Get()
    {
        MyDataContext _db = new MyDataContext();
        return _db.MyLINQUserTable.Select(u => new User(u, _db)).ToList();
    }
}

为了清楚起见,我在项目中已经使用了这种类型的模型(以上只是我在飞行中一起投入的一个例子)并且它运行良好。我的问题更多的是一个“学习”问题......我知道它有效。我只是不确定我是否应该采用不同的方式做更好的事情,如果有的话,为什么。

思想?

2 个答案:

答案 0 :(得分:0)

我认为这类问题没有正确的答案。这是设计,偏好和要求的问题。我会尽力表明我的看法......

我总是喜欢Repository pattern以保持关注点。我会使用类型为T的存储库来检索T实体(谈论泛型)。这些将是参与我的商业模式的实体。在你的情况下,我会有一个UsersRepository类,返回User个实体。此数据访问层(DAL)将处理我的数据访问问题

我的商业模式将使用实体来开展业务。在简单的CRUD应用程序中,可能不需要其他对象,而是我的存储库返回的实体。在更复杂的应用程序中,需要使用新类,使用DAL的存储库将数据检索为实体。此业务层将处理我的主要业务功能问题(计算等)

然后,出于显示目的,您可能需要另一种结构。例如,如果您按照MVC pattern(您还可以看到Microsoft article),则需要创建另一个模型以适合您的显示目的。遵循MVC模式的 GUI层将处理我的图形显示问题

希望我帮忙!

答案 1 :(得分:0)

这就是所谓的数据访问对象模式。 UserMyLINQUserClass的DAO,可称为域类。

DAO模式专为单一职责而设计:只有DAO“知道”数据层,而域类可以专注于业务逻辑。域类是持久性无知。到目前为止,非常好。

然而,这种模式存在(至少)三个很大的缺点:

  • 它倾向于创建大量的样板代码
  • 很难组合对象图,因为DAO只代表数据库中的一行,并且提取对象图很容易退化为每个对象或子对象集合的一个查询。
  • 交易难以处理,因为DAO无法管理跨越整个对象图的事务。所以你需要一些总体层来处理交易。

然而,大多数ORM具有与DAO不同的持久性 - 无知模型。他们有存储库和工作单元。在L2S中,Table是基本的存储库,上下文是工作单元。像MyLINQUserClass这样的“域”类可以被认为是持久性无知的。 (承认,它们充满了用于持久性和变更跟踪的样板代码,但它是生成的,实际上可以忽略它)。因此,已经分配了CRUD操作的所有责任,并且不需要承担这些责任的其他对象。

实现它的方式使得使用对象图和事务变得更加困难,因为每个DAO都有自己的上下文,因此您无法以LINQ转换为一个SQL语句的方式编写涉及多个DAO的LINQ查询。在一次交易中进行多次保存操作是一项挑战。

结论

通过在linq-to-sql环境中使用DAO,您可以混合使用CRUD职责。您将获得DAO模式的所有缺点,并且无法充分利用存储库/ UoW模式的强大功能。我强烈建议选择其中一个,我会选择L2S(嗯,实际上我会选择实体框架)。