我有:
类别类
public partial class Category : BaseEntity
{
...
public string Name { get; set; }
private ICollection<Discount> _appliedDiscounts;
public virtual ICollection<Discount> AppliedDiscounts
{
get { return _appliedDiscounts ?? (_appliedDiscounts = new List<Discount>()); }
protected set { _appliedDiscounts = value; }
}
}
服务:
public IList<Category> GetCategories()
{
// ado.net to return category entities.
}
public ICollection<Discount> GetDiscount(int categoryId)
{
// ado.net .
}
我不想像EF那样使用ORM ..但是简单的ado.net,我不想在我的域名定义中加入丑陋的Lazy<T>
,例如公共懒惰....
那么在这种情况下,如何在不使用Category类的Lazy<T>
声明的情况下自动将LinkedDiscounts绑定到GetDiscount?
答案 0 :(得分:2)
我不知道你为什么不喜欢Lazy<T>
类型 - 这很简单,很有用,你不用担心任何事情。
没有人强迫你使用public Lazy<IEnumerable<Discount>> GetDiscounts();
您可以在内部使用它:
Lazy<IEnumerable<Discount>> discounts = new Lazy<IEnumerable<Discount>>(() => new DiscountCollection());
public IEnumerable<Discount> GetDiscounts()
{
return discounts.Value;
}
它按预期运作 - 直到没有人要求折扣才能创造。
如果你真的想要 - 你可以创建自己的实现。像里希特的单身人士课程&#34; CLR通过C#&#34; book(因为Lazy具有适当的单例容器的所有属性 - 线程安全性,只能评估一个内部&#39; singleton&#39;值的实例...)。
但你真的想创造并测试吗?您只需将一个精心设计的标准组件替换为可疑的标准组件。
在实际阅读您的问题之后
1)如果您的延迟加载不需要任何线程安全,即使没有任何Lazy或复杂结构,您也可以完成类似的行为 - 只需使用Func委托:
public partial class Category : BaseEntity
{
...
private Func<ICollection<Discount>> getDiscounts;
public Category(Func<ICollection<Discount>> getDiscounts) { ... }
public string Name { get; set; }
private ICollection<Discount> _appliedDiscounts;
public virtual ICollection<Discount> AppliedDiscounts
{
get { return _appliedDiscounts ??
(_appliedDiscounts = new List<Discount>(this.getDiscounts())); }
protected set { _appliedDiscounts = value; }
}
}
public IList<Category> GetCategories()
{
// ado.net to return category entities.
... = new Category(() => this.GetDiscount((Int32)curDataObject["categoryId"]))
}
public ICollection<Discount> GetDiscount(int categoryId)
{
// ado.net .
}
如果您注入服务,那将更加简单:
public virtual ICollection<Discount> AppliedDiscounts
{
get { return _appliedDiscounts ??
(_appliedDiscounts = new List<Discount>(this.service.GetDiscounts(this.CategoryId))); }
protected set { _appliedDiscounts = value; }
}
2)如果你需要在多个线程中使用这些对象,那么你将不得不重新设计你的类 - 它们看起来不像线程安全。
评论后
我想做的就是这个人 stackoverflow.com/questions/8188546 / ...我想知道这个概念是怎么回事 像EF这样的ORM对域进行处理,保持清洁并与之分离 注入服务类但仍然能够处理延迟加载。我知道 我可以使用Reflection来获取所有对象属性及其对象 变量(如AppliedDiscounts),但不要&#39;知道如何改造 这些动态变为惰性类型,以便以后可以加载 需要的。
普遍的原则是,你无法得到任何东西。你不能让你的实体干净并与任何服务分开(甚至通过一些代理),并允许他们懒得加载 - 如果他们不了解服务和服务,就不知道关于他们的任何事情然后如何延迟加载工作?没有办法实现这样的绝对解耦(对于两个组件进行交互,他们必须要么彼此了解,知道某些第三个模块 - 通信器,或者某些模块应该知道它们。但是这种耦合可能部分或完全隐藏。
提供实体对象模型的技术通常使用以下某些技术:
context.Orders.With("OrderDetails")
。积极的一面是实体将是干净的。对于您的自定义对象模型2或3是最好的投注。但你可以尝试Roslyn
1