我不熟悉域驱动设计,最近我开始为项目创建域模型.我还没有决定使用ORM(虽然我可能会选择NHibernate)而且我目前正在努力确保我的Value Objects应该就是这样.
我有一些VO除了封装"喜欢"术语之外几乎没有任何行为,例如:
public class Referral {
public Case Case { get; set; } // this is the a reference to the aggregate root
public ReferralType ReferralType { get; set; } // this is an enum
public string ReferralTypeOther { get; set; }
} // etc, etc.
Run Code Online (Sandbox Code Playgroud)
这个特殊的类有一个参考"案例",这是两个级别,所以如果说我要访问推荐我可以去:case.social.referral(案例,社交和推荐都是所有类,有一个单一的社交在一个案例中,社交中有一个推荐).现在,当我输入它时我正在查看它,我认为我不需要推荐中的案例,因为它可以通过社交实体访问,对吗?
现在,毫无疑问,我认为这应该是一个VO,而我计划用来将其保存到数据库的方法是让NHibernate为它分配一个代理标识符(我仍然不太清楚) ,如果有人可以请详细说明它也会帮助我,因为我不知道代理标识符是否要求我已经在我的VO中有一个Id,或者它是否可以在没有一个的情况下运行)和/或受保护的Id属性不会在Referral类之外暴露(仅用于持久保存到DB).
现在转到我的标题问题:VO应该有一个集合,(在我的情况下是一个List)里面吗?我只能将其视为数据库中的一对多关系,但由于没有身份,因此使类成为实体似乎不够.以下是代码:
public class LivingSituation {
private IList<AdultAtHome> AdultsAtHome { get; set; }
public ResidingWith CurrentlyResidingWith { get; set } // this is an enum
} // etc, etc.
Run Code Online (Sandbox Code Playgroud)
这个类目前没有Id,而AdultsAtHome类只有内在类型(string,int).所以我不确定这是否应该是一个实体,或者它是否可以作为VO保留,我只需要使用自己的表和私有/受保护的Id字段将我的ORM配置为使用1:m关系,以便ORM可以持久保存到DB.
另外,我应该为每个课程使用规范化表格吗?我想我只需要为每个类使用一个表,当有可能将类的多个实例分配给实体或值对象时和/或有可能与这些对象中的某些对象具有集合1:m的关系.对于具有内部类型但具有嵌套类型的某些值对象使用单个表我没有问题我认为使用规范化表是有利的.对此有何建议? …
一旦我在NHibernate中映射了我的域,我怎样才能在我的代码中的其他地方反向查找这些映射?
例:
由于Pony某种原因,该实体被映射到名为"AAZF1203"的表.(愚蠢的遗留数据库表名!)我想只使用typeof(Pony)因为我必须在其他地方编写查询来从NH映射中找出该表名.
private const string LegacyPonyTableName = "AAZF1203";
[Test]
public void MakeSureThatThePonyEntityIsMappedToCorrectTable()
{
string ponyTable = GetNHibernateTableMappingFor(typeof(Pony));
Assert.AreEqual(LegacyPonyTableName, ponyTable);
}
Run Code Online (Sandbox Code Playgroud)
换句话说,GetNHibernateTableMappingFor(Type t)需要看起来像什么?
我试图从连接表中获取单个属性,其中我的主表中的非PK连接到外表的PK.下面是我想要完成的一个过于简单的例子(我不想引用外国实体):
表:
CREATE TABLE Status
(
Id int,
Body text,
CategoryId int
)
CREATE TABLE Category
(
Id int,
Name text
)
Run Code Online (Sandbox Code Playgroud)
SQL生成:
SELECT Id, Body, CategoryId, Category.Name AS CategoryName
FROM Status
LEFT JOIN Category ON Category.Id = Status.CategoryId
Run Code Online (Sandbox Code Playgroud)
我试图在StatusMap中映射这样的连接,但它似乎加入了两个主键(其中Status.Id = Category.Id):
Join("Category" m =>
{
m.Optional();
m.KeyColumn("CategoryId");
m.Map(x => x.CategoryName, "Name");
});
Run Code Online (Sandbox Code Playgroud) 我试图使用延迟加载我的一个实体的属性
属性映射是这样的:
<property name="Foobar" type="AnsiString" column="FOOBAR" lazy="true"/>
Run Code Online (Sandbox Code Playgroud)
但是当我要保存这个实体的实例(使用Linq)时,它会抛出一个带有以下内部异常的DatabaseQueryException:
NHibernate.MappingException:没有持久性:Castle.Proxies.FooEntityProxy"
当我删除lazy ="true"项时,异常不再被抛出.使用lazy ="true"有什么问题以及如何解决这个问题?
我有几个项目使用NH和FNH生成映射(一些Fluent一些Automapped).我仍然需要一些bug和缺少的功能,但似乎FNH可能因为集成到NHibernate中的代码映射而死亡.
问题:有助于FNH或将映射迁移到代码映射或confORM并修复问题/实现功能吗?
nhibernate nhibernate-mapping fluent-nhibernate nhibernate-mapping-by-code fluent-nhibernate-mapping
我有一个NHibernate Linq查询,它没有按我的预期工作.
问题似乎来自于在where子句中使用左连接表中的可空int列.这导致连接充当内连接.
var list = this.WorkflowDiaryManager.WorkflowActionRepository.All
.Fetch(x => x.CaseView)
.Fetch(x => x.WorkflowActionType)
.ThenFetchMany(x => x.WorkflowActionPriorityList)
.Where(x => x.AssignedUser.Id == userId || x.CaseView.MooseUserId == userId)
Run Code Online (Sandbox Code Playgroud)
由此产生的SQL看起来像(从加入开始 - 您不需要查看所有选择)
from Kctc.WorkflowAction workflowac0_
left outer join Kctc.WorkflowCaseView workflowca1_ on workflowac0_.CaseId=workflowca1_.CaseId
left outer join Kctc.WorkflowActionType workflowac2_ on workflowac0_.WorkflowActionTypeId=workflowac2_.WorkflowActionTypeId
left outer join Kctc.WorkflowActionPriority workflowac3_ on workflowac2_.WorkflowActionTypeId=workflowac3_.WorkflowActionTypeId
,Kctc.WorkflowCaseView workflowca4_
where workflowac0_.CaseId=workflowca4_.CaseId
and (workflowac0_.AssignedUser=@p0 or workflowca4_.[MooseUserId]=@p1);
@p0 = 1087 [Type: Int32 (0)],
@p1 = 1087 [Type: Int32 (0)]
Run Code Online (Sandbox Code Playgroud)
因此导致问题的部分是上面代码段的第5行.正如您所看到的,NHibernate正在尝试在WorkflowCaseView View上进行"老派"连接.这会导致查询排除WorkflowAction表中没有CaseId的其他有效操作.
任何人都可以解释为什么NHibernate正在编写这个SQL,以及我如何鼓励它产生更好的查询?
谢谢!
WorkflowActionMap中的重要位
Table("Kctc.WorkflowAction");
Id(x => …Run Code Online (Sandbox Code Playgroud) 我正在使用NHibernate进行一些测试,我目前有两个映射实体,Orders和Products.一如既往,Order有一系列产品,我将其映射为:
<bag name="Products" cascade="all" lazy="true">
<key column ="Order_ID" />
<many-to-many class="Product" column="Product_ID" />
</bag>
Run Code Online (Sandbox Code Playgroud)
在C#方面:
public virtual IList<Product> Products
{
get { return _Products; }
set { _Products = value; }
}
private IList<Product> _Products = new List<Product>();
Run Code Online (Sandbox Code Playgroud)
如果我在数据库中有一个持久订单(约翰的订单),其产品集合中有一些项目(苹果,橙子和椰子),我尝试在集合中添加一个新项目(香蕉)我可以看到从NHibernate做的事情的SQL输出:
INSERT INTO Products_Table (Product_Name, Product_ID) VALUES ('Banana', @Banana_ID)
DELETE FROM Products WHERE Order_ID = @Johns_Order_ID
INSERT INTO Products (Order_ID, Product_ID) VALUES (@Johns_Order_ID, @Apple_ID)
INSERT INTO Products (Order_ID, Product_ID) VALUES …Run Code Online (Sandbox Code Playgroud) 我在不同项目之间IWindsorContainer和之间使用了两种类型的容器来IUnityContainer进行服务和接口绑定.但是我不确定有什么区别?他们有相同的功能吗?如果是,那么在现有的情况下需要开发另一个.或者他们有一些差异?如果是,那是什么?我将使用哪一个目的?我有一个小文件来反对这种混乱,但我没有安静地抓住它.所以,如果你让我知道,那么我将不胜感激.请注意,我在NHibernet这里使用映射.
asp.net-mvc entity-framework nhibernate-mapping fluent-nhibernate
我有以下型号:
<class name="Person" table="Person" optimistic-lock="version">
<id name="Id" type="Int32" unsaved-value="0">
<generator class="native" />
</id>
<!-- plus some properties here -->
</class>
<class name="Event" table="Event" optimistic-lock="version">
<id name="Id" type="Int32" unsaved-value="0">
<generator class="native" />
</id>
<!-- plus some properties here -->
</class>
<class name="PersonEventRegistration" table="PersonEventRegistration" optimistic-lock="version">
<id name="Id" type="Int32" unsaved-value="0">
<generator class="native" />
</id>
<property name="IsComplete" type="Boolean" not-null="true" />
<property name="RegistrationDate" type="DateTime" not-null="true" />
<many-to-one name="Person" class="Person" column="PersonId" foreign-key="FK_PersonEvent_PersonId" cascade="all-delete-orphan" />
<many-to-one name="Event" class="Event" column="EventId" foreign-key="FK_PersonEvent_EventId" cascade="all-delete-orphan" />
</class>
Run Code Online (Sandbox Code Playgroud)
在Person和Event中都没有指向PersonEventRegistration的属性.
当我尝试从PersonEventRegistration中删除条目时,出现以下错误:
"deleted object …Run Code Online (Sandbox Code Playgroud) 我希望有人可以帮我解决这个问题.我一直在绞尽脑汁,我的项目很快到期.先感谢您.
插入新记录时,我收到超出范围异常的索引.在无休止地搜索信息后,有人建议我的映射中的列值与我的持久化类中的列值不匹配.但是,我计算并重新计算,它们似乎匹配.正如您在下面的代码中所看到的,我正在使用NHibernate.Mapping.Attributes来进行映射.也许我在那里做错了什么.
我终于下载了NHibernate源代码并通过我的问题进行了调试.下面是NHibernate试图构建的insert语句:
{插入WTSLIB33T.PRODDATA(PSTAT,PCONO,PDVNO,PWKTY,PCRTY,PTSID,PCNNO,PDTTK,PJBNO,PSJNO,PTKNO,PCWNO,PWKAR,PWKDC,PWKCD,PCNWO,PWDNO,PDESC,PDCCD,PHRS,PUNIT,PSEQ ,PCUST)VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? )}
如您所见,参数数量与列表中的字段数相匹配.我还将这个生成的插入与我的类相匹配,我发现PSEQ和PCUST列与我的持久类无关.然后,在通过Dehydrate函数进行调试时,我发现了两个可能的问题.第一个是我注意到对NullSafeSet函数的调用将参数0设置为我的PSEQ字段应该设置为什么,但insert语句中的参数0是PSTAT.
我注意到的第二个问题是最后一次调用"index + = ArrayHelper.CountTrue(includeColumns [i]);" 在Dehydrate函数中,将索引变量保留为23,这是正确的; 但是,下一个调用"IdentifierType.NullSafeSet(statement,id,index,session);" ,它检查行id,传入索引23,这将超出范围.对于基于零的数组,该值应为22.
protected int Dehydrate(object id, object[] fields, object rowId, bool[] includeProperty, bool[][] includeColumns, int table, IDbCommand statement, ISessionImplementor session, int index)
{
if (log.IsDebugEnabled)
{
log.Debug("Dehydrating entity: " + MessageHelper.InfoString(this, id, Factory));
}
// there's a pretty strong coupling between the order of the SQL parameter
// construction and the actual order of the parameter collection.
for (int i = 0; i < entityMetamodel.PropertySpan; i++)
{ …Run Code Online (Sandbox Code Playgroud)