加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 存储库,工厂和分层结构的数据

发布时间:2020-12-15 07:39:11 所属栏目:百科 来源:网络整理
导读:我正在通过Eric Evans的域驱动设计,他概述了存储库和工厂之间的相互作用.存储库本身将调用DB接口来获取结果集.然后将这个结果集传递给一个工厂,这个工厂将会理解这个结果集来重组对象. 如果数据本质上是分层的,就像某种树结构一样.例如: public class Foo{
我正在通过Eric Evans的域驱动设计,他概述了存储库和工厂之间的相互作用.存储库本身将调用DB接口来获取结果集.然后将这个结果集传递给一个工厂,这个工厂将会理解这个结果集来重组对象.

如果数据本质上是分层的,就像某种树结构一样.例如:

public class Foo
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Foo Parent { get; set; }
    public ICollection<Foo> { get; set; }

    // Other business like methods here

}

使用DDD我将有我的接口和实现:

public interface IFooRepository
{
    Foo Get(int id);
}

public interface IFooFactory<TSource>
{
    Foo Create(TSource source);
}

public class SqlFooRepository: IFooRepository
{
    private readonly IFooDao dao;
    private readonly IFooFactory<SqlDataReader> factory;

    public SqlFooRepository(IFooDao dao,IFooFactory factory)
    {
        this.dao = dao;
        this.factory = factory;
    }

    public Foo Get(int id)
    {
        var resultSet = dao.Find(id);
        return factory.Create(resultSet);
    }
}

public class SqlFooFactory: IFooFactory<SqlDataReader>
{
    public Foo Get(SqlDataReader reader)
    {
        var foo = new Foo();
        foo.Id = (int) reader["id];
        foo.Name = (string) reader["name"];
            // Do I build the children accounts here
        return foo;
    }
}

如果我试图在工厂里修建孩子,那么我需要再次访问这个回购站.如果我在回购中做到这一点,我觉得我正在做工作,应该是工厂.不知道如何解决这个问题.

有一个想法是,Foo不是聚合根,而是FooTree是总根.所以试图获得任何Foo,我需要创建整个树,这意味着我可以将Foo对象的集合传递到FooTreeFactory.

任何帮助将非常感激.

解决方法

假设您在Foo工作时需要所有的孩子,您应该在存储库中获取它们,并重建工厂中的层次结构.如果你不一定需要他们;或者您可能需要在某些情况下使用它们,您可以考虑轻松抓取它们,但我认为这不是您在此之后.

当构建这样的层次结构时,您需要确保只打数据库一次.例如,如果您在一次调用db中获取Foo foo1,然后使用相同的存储库方法repo.Get(foo1.Id)获取foo1的子项,那么您将为每个子级添加一个额外的db往返. ..然后一些更多,如果你递归地为每个孩子也.您不希望这样做,因为这将导致未知数量的额外的数据库往返(select N+1 problem的变体).

你想要的是一个在一个数据库往返中获取完整层次结构的存储库.如果您正在使用ORM,那么通常ORM有一些内置的东西来处理这个;例如NHibernate has a DistinctRootEntityResultTransformer这样做.

如果要使用plain-sql存储库,那么我将创建一个存储过程(假设您正在使用Sql Server)从数据库中循环获取层次结构中的所有Foo行,并将它们返回到存储库.存储库然后将此结果集传递到工厂以创建对象树.

所以关键是不要将单个Foo传递给您的工厂,而是将阅读器传递给读取Foo行结果集的工厂,而不是单行.

更新

重读了你的问题后,我想你和@enrico都是:

[…] the FooTree is the aggregate root. So trying to get any Foo I would
need to create the entire tree,which means I could pass a collection
of Foo objects to a FooTreeFactory

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读