Repository模式没有一个ORM [英] Repository Pattern without an ORM

查看:140
本文介绍了Repository模式没有一个ORM的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用在不使用ORM的.NET C#应用程序库的模式。但是我遇到的问题是如何填补一到多的实体列表属性。例如如果客户有订单列表即如果客户类有一个名为订单列表财产和我的仓库有一个名为GetCustomerById方法,然后?




  • 我应该在GetCustomerById方法中加载订单列表?

  • 如果该命令本身有另一个列表属性等等?

  • 如果有什么我想做懒加载?我会在哪里把代码加载客户订单的财产?内部订单属性get {}访问器?但后来我不得不库注入到域实体?我不认为这是正确的解决方案。



这也引发了类似变化跟踪,删除等功能的问题?因此,我认为最终的结果是我可以做DDD没有ORM?



但现在我只是在延迟加载列表属性在我的领域中的实体有兴趣吗?任何想法?



纳比勒



我假定这是不使用的ORM的人一个很常见的问题一个领域驱动设计?任何想法?


解决方案

我可以做DDD没有ORM?




可以,但一个ORM简化的东西。



说实话,我觉得你的问题不是做你是否需要一个ORM与否 - 这是你正在考虑太多的数据,而不是行为,是与DDD成功的关键。在数据模型而言,大多数实体将具有关联到最另一个实体在某种形式的,并且从这个角度可以遍历所有围绕模型。这是它看起来像你的客户和订单,也许就是为什么你认为你需要延迟加载。但是,你需要用聚集打破这些关系成组的行为。



例如,为什么你模拟的客户总有顺序列表?如果答案是因为客户可以有订单那我不知道你在DDD的心态是。



什么行为有需要的客户有订单列表?当你更多地考虑到您的域名的行为(即什么数据需要在什么时候),你可以围绕用例和事物根据您的聚集模型变得更清晰,更容易因为你只改变一小物体跟踪在总量上边界。



我怀疑,客户应该是没有订单列表的单独聚合和顺序应该是与订单行列表的集合。如果你需要每个订单执行操作的客户,然后使用orderRepository.GetOrdersForCustomer(的customerID);进行更改,然后使用orderRespository.Save(顺序);



对于没有ORM有,你可以做到这一点各种方式变更跟踪,例如订单总量可能会引发事件该订单信息库收听已删除订单行。当工作单元完成这些可能随后被删除。 。或略少优雅的方式是保持删除列表,即order.DeletedOrderLines,你的资料库可以明显读



要信息Summarise:




  • 我认为你需要更多地考虑行为不是数据

  • ORM的让生活更轻松更改跟踪,但你可以做到无一你绝对可以做DDD无一



编辑回应评论:



我不认为我会执行延迟加载订单行。什么操作,你可能不需要的命令行的顺序上执行?不是很多,我怀疑。



不过,我不是一个局限于DDD的规则时,似乎有道理没有,那么......如果不可能场景,还有一些订单对象上执行的操作是不需要的命令行来填充经常有大量的相关联的订单订单行(都必须是真的为我认为这是一个问题),那么我会做这样的:



您可以在订单对象这个私人领域:

 私人Func键< GUID,请IList的<&订单行GT;> _lazilyGetOrderLines; 



哪些将由顺序库传递到订单上创建



 订购订购=新订单(this.GetOrderLines); 



如果这是在OrderRepository一个私有方法:

 私人的IList<&OrderLine的GT; GetOrderLines(GUID的orderId)
{
// DAL代码在这里

}

然后在命令行属性可能看起来像:

 公共IEnumberable<订单行> OrderLines 
{
得到
{
如果(_orderLines == NULL)
_orderLines = _lazilyGetOrderLines(this.OrderId);

返回_orderLines;
}
}



编辑2



我发现里面有类似的解决方案,以我的,但稍微更优雅这篇博客文章:



http://thinkbeforecoding.com/post/2009/02/07/Lazy-load-and -persistence-无知


I am using repository pattern in a .NET C# application that does not use an ORM. However the issue I am having is how to fill One-to-many List properties of an entity. e.g. if a customer has a list of orders i.e. if the Customer class has a List property called Orders and my repository has a method called GetCustomerById, then?

  • Should I load the Orders list within the GetCustomerById method?
  • What if the Order itself has another list property and so on?
  • What if I want to do lazy loading? Where would I put the code to load the Orders property in customer? Inside the Orders property get{} accessor? But then I would have to inject repository into the domain entity? which I don't think is the right solution.

This also raises questions for Features like Change Tracking, Deleting etc? So i think the end result is can I do DDD without ORM ?

But right now I am only interested in lazy loading List properties in my domain entities? Any idea?

Nabeel

I am assuming this is a very common issue for anyone not using an ORM in a Domain Driven Design? Any idea?

解决方案

can I do DDD without ORM ?

Yes, but an ORM simplifies things.

To be honest I think your problem isn't to do with whether you need an ORM or not - it's that you are thinking too much about the data rather than behaviour which is the key for success with DDD. In terms of the data model, most entities will have associations to most another entities in some form, and from this perspective you could traverse all around the model. This is what it looks like with your customer and orders and perhaps why you think you need lazy loading. But you need to use aggregates to break these relationships up into behavioural groups.

For example why have you modelled the customer aggregate to have a list of order? If the answer is "because a customer can have orders" then I'm not sure you're in the mindset of DDD.

What behaviour is there that requires the customer to have a list of orders? When you give more thought to the behaviour of your domain (i.e. what data is required at what point) you can model your aggregates based around use cases and things become much clearer and much easier as you are only change tracking for a small set of objects in the aggregate boundary.

I suspect that Customer should be a separate aggregate without a list of orders, and Order should be an aggregate with a list of order lines. If you need to perform operations on each order for a customer then use orderRepository.GetOrdersForCustomer(customerID); make your changes then use orderRespository.Save(order);

Regarding change tracking without an ORM there are various ways you can do this, for example the order aggregate could raise events that the order repository is listening to for deleted order lines. These could then be deleted when the unit of work completed. Or a slightly less elegant way is to maintain deleted lists, i.e. order.DeletedOrderLines which your repository can obviously read.

To Summarise:

  • I think you need to think more about behaviour than data
  • ORM's make life easier for change tracking, but you can do it without one and you can definitely do DDD without one.

EDIT in response to comment:

I don't think I'd implement lazy loading for order lines. What operations are you likely to perform on the order without needing the order lines? Not many I suspect.

However, I'm not one to be confined to the 'rules' of DDD when it doesn't seem to make sense, so... If in the unlikely scenario that there are a number of operations performed on the order object that didn't require the order lines to be populated AND there are often a large number of order lines associated to an order (both would have to be true for me to consider it an issue) then I'd do this:

Have this private field in the order object:

private Func<Guid, IList<OrderLine>> _lazilyGetOrderLines;

Which would be passed by the order repository to the order on creation:

Order order = new Order(this.GetOrderLines);

Where this is a private method on the OrderRepository:

private IList<OrderLine> GetOrderLines(Guid orderId)
{
    //DAL Code here

}

Then in the order lines property could look like:

public IEnumberable<OrderLine> OrderLines
{ 
    get 
    {
         if (_orderLines == null)
            _orderLines = _lazilyGetOrderLines(this.OrderId);

         return _orderLines;
    }
}

Edit 2

I've found this blog post which has a similar solution to mine but slightly more elegant:

http://thinkbeforecoding.com/post/2009/02/07/Lazy-load-and-persistence-ignorance

这篇关于Repository模式没有一个ORM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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