Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用PetaPoco的透明延迟加载_C#_Petapoco_Castle Dynamicproxy - Fatal编程技术网

C# 使用PetaPoco的透明延迟加载

C# 使用PetaPoco的透明延迟加载,c#,petapoco,castle-dynamicproxy,C#,Petapoco,Castle Dynamicproxy,我在以前的企业应用程序中使用过NHibernate,但其复杂的设置和分散的文档促使我在下一个应用程序中尝试使用更简单的PetaPoco。我面临的主要问题是实现透明延迟加载以支持以下场景: public class Customer { public string CustomerName { get; set; } public List<Order> Orders { get; set; } // Orders should be lazy-loaded } pu

我在以前的企业应用程序中使用过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; }
}
公共类客户{
公共字符串CustomerName{get;set;}
公共列表命令{get;set;}//应延迟加载命令
}
公共阶级秩序{
公共Int32订单号{get;set;}
公共列表产品{get;set;}//应延迟加载产品
}
公共类产品{
公共字符串ProductName{get;set;}
}
我想我需要使用它,但我很难理解如何实现拦截器,该拦截器将拦截对getter的调用,并触发对相关订单或产品的检索。还有,一旦我拥有了拦截器,当我使用PetaPoco检索数据时,如何确保它被使用

如蒙协助,将不胜感激

提前谢谢


编辑:@Groo:我正在考虑在PetaPoco select函数上创建一个层,为相关集合添加拦截器(使用自定义属性),例如:

公共类ReferencedByAttribute:Attribute
{
公共字符串ForeignKeyPropertyName{get;set;}
公共引用的ByAttribute(字符串foreignKeyPropertyName)
{
this.ForeignKeyPropertyName=ForeignKeyPropertyName;
}
}
使用Castle.DynamicProxy;
公共类LazyLoadingInterceptor:I Interceptor
{
公共无效拦截(IInvocation调用)
{
//TODO:拦截对getter的第一个调用,并从数据库中检索相关对象
invocation.procedure();
}
}
公共级佩塔波科说唱机{
公共列表获取(字符串sql){
PetaPoco.Database db=新的PetaPoco.Database(“connectionstring”);
List entities=db.Fetch(sql);
ProxyGenerator=新的ProxyGenerator();
foreach(实体中的T实体)
{
foreach(entity.GetType().GetProperties()中的PropertyInfo pi)
{
if(pi.GetCustomAttributes(typeof(ReferencedByAttribute),true).Count()==1){
SetValue(entity,generator.CreateClassProxy(pi.PropertyType,new LazyLoadingInterceptor()),null);
}
}
}
返回实体;
}
}

你必须用老式的方法来做

    private IList<Product> _Items;
    public IList<Product> Items {
        get {
            if (_Items == null) {
                _Items = DbHelper.CurrentDb().Fetch<Product>("SELECT ..");
            }
            return _Items;
        }
        set {
            _Items = value;
        }
    }
私有IList\u项目;
公共物品{
得到{
如果(_Items==null){
_Items=DbHelper.CurrentDb().Fetch(“选择…”);
}
退货(物品);;
}
设置{
_项目=价值;
}
}

我知道这不是你想要的答案,但既然英孚和NH都支持这种开箱即用的方式,你为什么要重新发明轮子呢?尤其是如果您以前已经使用过NH?像这样的类几乎完全是“按约定”映射的,因此您基本上只需要指定要映射的属性。至于您的实际问题,实现这一点的唯一方法是修改PetaPoco源,即应该获取数据的部分。您希望阻止PetaPoco获取实际数据,而是创建一个代理,该代理将保留对
PetaPoco.Database
实例的引用,以便在首次访问任何类似集合的属性时重用它。现在想想包含外键的表,它们也需要惰性地实例化它们,您会发现这不是一项容易的任务。编写这段代码可能很有趣,但它肯定不会使ORM“简单得多”。@Groo:谢谢你的建议。我之所以想重新发明这个特殊的轮子,有几个原因:PetaPoco的设置速度更快,它在模型层中需要更少的编码,而且在检索数据方面似乎更快。此外,公司标准规定使用NH或PetaPoco(我没有EF)。如果NH有一套整合了最佳实践的可靠的集中教程,那么我们的开发人员学习和维护将会非常容易。事实上,这有点像一场黑匣子噩梦。好吧,我们已经使用它一段时间了,我们发现它使用起来相当简单。我想它可能取决于您的特定用例,但是使用它几乎可以在几分钟内运行(尽管我们从一开始就使用脚本化的.hbm配置文件)。此外,从NH3.0开始,LINQ提供者得到了极大的改进。如果没有其他内容,您就可以真正拥有POCO对象(如果需要创建自定义映射规则,PetaPoco需要将特定属性添加到域层中的实体)。当您必须创建NHibernate配置文件、会话管理器类、会话HTTP模块类、,存储库模式实现、日志记录、实体类、映射类、DAO类和运行NHibernate验证的框架?另外,您如何确定在会话管理器和会话HTTP模块类中实现什么?再次感谢。我当然考虑过这个解决方案,但希望找到一种对开发人员更透明的方法,可以在编写新系统时节省时间。Petapoco是一种微型ORM,你不会发现这种东西。我知道Petapoco是一种微型ORM,不会有这种现成的功能。这就是为什么我试图用这个功能扩展Petapoco。
    private IList<Product> _Items;
    public IList<Product> Items {
        get {
            if (_Items == null) {
                _Items = DbHelper.CurrentDb().Fetch<Product>("SELECT ..");
            }
            return _Items;
        }
        set {
            _Items = value;
        }
    }