【发布时间】:2009-07-05 08:28:41
【问题描述】:
TimeSheetActivity 类有一个分配集合。分配是一个值对象(不可变),看起来像这样:
public class Allocation : ValueObject {
public virtual StaffMember StaffMember { get; private set; }
public virtual TimeSheetActivity Activity { get; private set; }
public virtual DateTime EventDate { get ... }
public virtual TimeQuantity TimeSpent { get ... }
}
在域中使用这种关系最方便的方法是使用 IDictionary,即:
public virtual IEnumerable<Allocation> Allocations {
get { return _allocations.Values; } }
private readonly IDictionary<DateTime, Allocation> _allocations = new SortedList<DateTime, Allocation>();
我还需要能够通过 StaffMember 持久化和获取分配。如果这是一个数据驱动的设计,我的概念是会有一个分配表来解决活动和员工成员之间的多对多关系:
table Allocations
ActivityID
StaffMemberID
EventDate
TimeQuantity
我在可视化映射时遇到了问题。我正在尝试从 TimeSheetActivity 的分配开始,但是当我尝试生成 DDL 时出现以下错误:
NHibernate.MappingException: (XmlDocument)(3,6): XML 验证错误:命名空间 'urn:nhibernate-mapping-2.2' 中的元素 'class' 在命名空间 'urn:nhibernate- 中具有无效的子元素 'property'映射-2.2'。预期的可能元素列表:命名空间“urn:nhibernate-mapping-2.2”中的“元、子选择、缓存、同步、注释、tuplizer、id、复合id”。
我不知道我是否收到了错误,因为:
A). I haven't yet mapped StaffMember to a collection of Allocations.
B). The mapping I have between Activity and Allocations is wrong.
C). All of the above
D). Other _____________________________________
分配映射(在 FNH 中)
public class AllocationMap : IAutoMappingOverride<Allocation>
{
public void Override(AutoMap<Allocation> mapping)
{
// these are both derived from the time period, so ignore
mapping.IgnoreProperty(x => x.TimeSpent);
mapping.IgnoreProperty(x => x.EventDate);
// TimePeriodUserType knows how to persist the time period start and end dates as DateTimes
mapping.Map(x => x.TimeSpentPeriod)
.ColumnNames.Add("PeriodStart", "PeriodEnd")
.SetAttribute("type", typeof(TimePeriodUserType).AssemblyQualifiedName);
mapping.References(x => x.Activity).WithForeignKey().FetchType.Join().Not.Nullable();
mapping.References(x => x.StaffMember).WithForeignKey().FetchType.Join().Not.Nullable();
}
}
分配映射(生成的hbm)
....
<property name="TimeSpentPeriod" type="..., ..., ...">
<column name="PeriodStart" />
<column name="PeriodEnd" />
</property>
<many-to-one foreign-key="FK_AllocationToStaffMember" fetch="join" not-null="true" name="StaffMember" column="StaffMemberID" />
<many-to-one foreign-key="FK_AllocationToActivity" fetch="join" not-null="true" name="Activity" column="TimeSheetActivityID" />
....
活动映射 (FNH)
public class TimeSheetActivityMap : IAutoMappingOverride<TimeSheetActivity>
{
public void Override(AutoMap<TimeSheetActivity> mapping)
{
// this can be replaced by some id given by NHib via an inheritance type mapping??
mapping.IgnoreProperty(x => x.IdScheme);
// this is derived
mapping.IgnoreProperty(x => x.TotalTime);
// this is for client consumption only
mapping.IgnoreProperty(x => x.Allocations);
mapping.HasMany(x => x.Allocations)
.AsMap(x => x.EventDate)
.Cascade.All()
.Access.AsCamelCaseField(Prefix.Underscore)
.WithForeignKeyConstraintName("FK_ActivityAllocation");
}
}
ActivityMapping(生成的hbm)
<set name="Allocations" cascade="all" access="field.camelcase-underscore">
<key foreign-key="FK_ActivityAllocation" column="TimeSheetActivityID" />
<one-to-many class="Smack.ConstructionAdmin.Domain.Model.TimeSheet.Allocation, ..." />
</set>
根据我在 NHibernate 方面的经验,这是一个复杂的映射,因此,如果对映射技术、建模概念或我的解决方法有任何帮助、问题或批评,我将不胜感激。
干杯, 浆果
【问题讨论】:
标签: c# nhibernate fluent-nhibernate nhibernate-mapping domain-driven-design