【问题标题】:How to map this model如何映射此模型
【发布时间】: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


    【解决方案1】:

    我不是 FHN 方面的专家,但我看到您的 Allocations 属性是作为 Set 生成的。你应该得到一个像这样的 Map 元素:

    <map name="Allocations" lazy="true" table="Allocations">
    <key column="FK_ActivityAllocation"/>
    <index column="EVENT_DATE" type="DateTime"/>
    <composite-element class="Allocation">
    ...
    </composite>
    </map>
    

    这里有一些高级示例: http://ayende.com/Blog/archive/2009/06/03/nhibernate-mapping-ndash-ltmapgt.aspx

    【讨论】:

    • 确实应该,而且现在我改变了我的模型;我将分配设置为实体,这在我的框架中意味着它最终会带有一个 ID,该 ID 将方便地用作关联表的代理键。这就提出了一个问题,即 Allocation 是否真的一直是我的域模型中的一个实体,或者我是否在虚化一组值类型以使其工作(如果是这样,是否有更清洁的方法来获得代理键还是应该使用复合键或..)。无论如何,感谢您的提示,并感谢我需要阅读的 Ayende 帖子!干杯
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-06-11
    • 2023-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-22
    相关资源
    最近更新 更多