Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/reporting-services/3.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
Oop 用nhibernate进行域设计_Oop_Nhibernate_Orm_Class Design - Fatal编程技术网

Oop 用nhibernate进行域设计

Oop 用nhibernate进行域设计,oop,nhibernate,orm,class-design,Oop,Nhibernate,Orm,Class Design,在我的领域中,我有一个叫做Project的东西,它基本上拥有许多简单的配置属性,这些属性描述了当项目执行时应该发生什么。当项目被执行时,它会产生大量的LogEntries。在我的应用程序中,我需要分析给定项目的这些日志条目,因此我需要能够部分连续地从数据库(Oracle)加载部分(时间范围)日志条目。如何将这种关系建模为DB表和对象 我可以有一个Project表和ProjectLog表,并且有一个外键指向Project的主键,在对象级别执行“相同”的操作,有classProject和一个属性 I

在我的领域中,我有一个叫做
Project
的东西,它基本上拥有许多简单的配置属性,这些属性描述了当项目执行
时应该发生什么。当项目被执行时,它会产生大量的
LogEntries
。在我的应用程序中,我需要分析给定项目的这些日志条目,因此我需要能够部分连续地从数据库(Oracle)加载部分(时间范围)日志条目。如何将这种关系建模为DB表和对象

我可以有一个
Project
表和
ProjectLog
表,并且有一个外键指向
Project
的主键,在对象级别执行“相同”的操作,有class
Project
和一个属性

IEnumerable日志项{get;}

让NHibernate做所有的映射。但在这种情况下,我将如何设计ProjectRepository?我可以有一个方法

void FillLog(Project projectToFill、DateTime start、DateTime end)

我如何告诉NHibernate在有人调用此方法之前不应加载日志项,我如何让NHibernate在该方法中加载特定的时间段


我对ORM很陌生,也许这种设计对NHibernate来说不是最优的,或者一般来说?也许我应该以不同的方式设计它?

与其将项目实体作为一个实体,为什么不将引用四处移动,让
LogEntry
具有
产品
属性,并充当一个实体呢


与其将项目实体作为一个实体,为什么不将引用四处移动,并让
LogEntry
具有
Product
属性,同时作为一个实体


在NHibernate下加载基于部分/过滤/标准的列表的“正确”方法是使用查询。有
lazy=“extra”
,但它不能满足您的需要

正如您已经注意到的,这打破了根聚合->子级的DDD模型。我在这个问题上挣扎了一段时间,因为首先我讨厌持久性问题会污染我的域模型,而且我永远无法让API表面看起来“正确”。所属实体类上的筛选器方法可以工作,但还远远不够

最后,我决定用一个名为
Query()
的受保护方法扩展我的实体基类(我所有的实体都继承自它,我知道这在现在有点不流行,但它至少让我能够始终如一地做这类事情),该方法采用一个定义关系的LINQ表达式,在存储库的引擎盖下,调用LINQ to NH并返回一个
IQueryable
,然后您可以根据需要查询它。然后,我可以在一个常规属性下对该调用进行外观处理

基类执行以下操作:

protected virtual IQueryable<TCollection> Query<TCollection>(Expression<Func<TCollection, bool>> selector)
        where TCollection : class, IPersistent
    {
        return Repository.For<TCollection>().Where(selector);
    }
受保护的虚拟IQueryable查询(表达式选择器)
其中t集合:类,IPersistent
{
返回Repository.For().Where(选择器);
}
(这里我应该注意,我的存储库实现直接实现
IQueryable
,然后将工作委托给NH
会话.Query()

facading的工作原理如下:

public virtual IQueryable<Form> Forms 
{ 
    get 
    { 
         return Query<Form>(x => x.Account == this); 
    } 
}
公共虚拟可查询表单
{ 
得到
{ 
返回查询(x=>x.Account==this);
} 
}
这将帐户和表单之间的列表关系定义为实际映射关系(表单->帐户)的逆关系

对于“无限”集合(集合中可能有无限数量的对象),这可以正常工作,但这意味着您不能直接在NHibernate中映射关系,因此不能直接在NH查询中使用该属性,只能间接使用

我们真正需要的是替换NHibernate的通用包、列表和集合实现,它知道如何使用LINQ提供程序直接查询列表。一个已被提议作为补丁(请参阅)。正如你所看到的,补丁没有完成或被接受,从我所看到的,提议者没有将其重新打包为一个扩展-迭戈·米耶尔松是这里的一个用户,所以也许他会插话。。。我已经测试了他的建议代码作为一个POC,它确实像广告宣传的那样工作,但显然它没有经过测试或保证,也不一定完整,它可能有副作用,而且没有使用或发布它的许可,你无论如何也不能使用它


除非NH团队着手编写/接受一个补丁来实现这一点,否则我们将不得不继续采取变通办法。NH和DDD对世界的看法存在冲突。

在NHibernate下加载部分/过滤/基于标准的列表的“正确”方法是使用查询。有
lazy=“extra”
,但它不能满足您的需要

正如您已经注意到的,这打破了根聚合->子级的DDD模型。我在这个问题上挣扎了一段时间,因为首先我讨厌持久性问题会污染我的域模型,而且我永远无法让API表面看起来“正确”。所属实体类上的筛选器方法可以工作,但还远远不够

最后,我决定用一个名为
Query()
的受保护方法扩展我的实体基类(我所有的实体都继承自它,我知道这在现在有点不流行,但它至少让我能够始终如一地做这类事情),该方法采用一个定义关系的LINQ表达式,在存储库的引擎盖下,调用LINQ to NH并返回一个
IQueryable
,然后您可以根据需要查询它。然后,我可以在一个常规属性下对该调用进行外观处理

基类执行以下操作:

protected virtual IQueryable<TCollection> Query<TCollection>(Expression<Func<TCollection, bool>> selector)
        where TCollection : class, IPersistent
    {
        return Repository.For<TCollection>().Where(selector);
    }
受保护的虚拟IQueryable查询(表达式选择器)
其中t集合:类,IPersistent
{
返回Repository.For().Where(选择器);
}
(这里我应该注意,我的存储库实现实现了
IQueryablepublic virtual IQueryable<Form> Forms 
{ 
    get 
    { 
         return Query<Form>(x => x.Account == this); 
    } 
}