我在以前的企业应用程序中使用过NHibernate,但其复杂的设置和分散的文档促使我在下一个应用程序中尝试使用简单得多的PetaPoco。我面临的主要问题是实现透明的延迟加载以支持以下场景:
public class Customer {
public string CustomerName { get; set; }
public List<Order> Orders { get; set; } // Orders should be lazy-loaded
}
public class Order {
public Int32 OrderNumber { get; set; }
public List<Product> Products { get; set; } // Products should be lazy-loaded
}
public class Product {
public string ProductName { get; set; }
}我认为我需要使用城堡DynamicProxy,但我很难理解如何实现拦截器,该拦截器将拦截对getter的调用并触发相关订单或产品的检索。而且,一旦我有了拦截器,如何确保它在我使用PetaPoco检索数据时被使用?
如能提供任何协助,将不胜感激。
提前谢谢。
编辑:@Groo:我正在考虑在PetaPoco选择函数之上创建一个层,以便为相关集合添加拦截器(使用自定义属性),例如:
public class ReferencedByAttribute : Attribute
{
public String ForeignKeyPropertyName { get; set; }
public ReferencedByAttribute(String foreignKeyPropertyName)
{
this.ForeignKeyPropertyName = foreignKeyPropertyName;
}
}
using Castle.DynamicProxy;
public class LazyLoadingInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
// TODO: Intercept first call to getter and retrieve related objects from the database
invocation.Proceed();
}
}
public class PetaPocoWrapper {
public List<T> Fetch<T>(String sql) {
PetaPoco.Database db = new PetaPoco.Database("connectionstring");
List<T> entities = db.Fetch<T>(sql);
ProxyGenerator generator = new ProxyGenerator();
foreach(T entity in entities)
{
foreach (PropertyInfo pi in entity.GetType().GetProperties())
{
if (pi.GetCustomAttributes(typeof(ReferencedByAttribute), true).Count() == 1) {
pi.SetValue(entity, generator.CreateClassProxy(pi.PropertyType, new LazyLoadingInterceptor()), null);
}
}
}
return entities;
}
}发布于 2014-04-30 20:33:46
你必须用老式的方式去做
private IList<Product> _Items;
public IList<Product> Items {
get {
if (_Items == null) {
_Items = DbHelper.CurrentDb().Fetch<Product>("SELECT ..");
}
return _Items;
}
set {
_Items = value;
}
}https://stackoverflow.com/questions/23381277
复制相似问题