Fluent Nhibernate Mapping - 值对象内的一对多?
Posted
技术标签:
【中文标题】Fluent Nhibernate Mapping - 值对象内的一对多?【英文标题】:Fluent Nhibernate Mapping - one-to-many inside a Value Object? 【发布时间】:2011-04-07 08:02:22 【问题描述】:您好,我正在努力优化/重构域模型,并试图将逻辑从应用程序服务转移到我的域模型中。现在我遇到了一个 NHibernate 问题。
该模型是一个 WorkEvaluation 类,其中包含一个带有问题的问卷模板,它还包含一个 QuestionWeight 类的集合。问题是 WorkEvaluation 类还有一个重要的属性 HitInterval,它属于 WorkEvaluation 中的 QuestionWeight 集合。这个概念是你通过回答很多问题来进行评估(这个例子中不包括答案),最后你应用一些权重(百分比权重)来修改答案分数。这意味着您可以使一些问题更重要,而另一些则不那么重要。命中间隔也是您在计算 TOTAL WorkEvaluation 分数(包括权重修改)时使用的调整参数,结果例如:Totalscore = 100,Hitinterval 5% 比我们得到的总间隔为 95-105,可用于匹配其他评价。
足够的背景。 我想将 QuestionWeights 和 HitInterval 的列表封装在值对象 QuestionScoreTuning 中,因为它们属于一起并且应该同时应用。 而且我还想在 QuestionScoreTuning 中添加一些不属于 workEvaluation 的业务逻辑。 我如何映射 i Fluent Nhibernate 具有一对多集合和 HitInterval 和引用的值对象(组件)?这是我当前的代码:
public class WorkEvaluation : DomainBase<long>, IAggregateRoot
public void ApplyTuning(QuestionScoreTuning tuning)
QuestionScoreTuning = tuning;
//TODO Raise Domain Event WorkEvaluationCompleted -
// which should recalculate all group scores
public QuestionScoreTuning QuestionScoreTuning get; protected set;
public class QuestionScoreTuning : ValueObject
private IList<QuestionWeight> _questionWeights;
public QuestionScoreTuning(IList<QuestionWeight> listOfWeights, long hitInterval)
_questionWeights = listOfWeights;
HitInterval = hitInterval;
public long HitInterval get; protected set;
protected override IEnumerable<object> GetAtomicValues()
return _questionWeights.Cast<object>();
/// <summary>
/// A list of all added QuestionWeights for this WorkEvaluation
/// </summary>
public IList<QuestionWeight> QuestionWeights
get return new List<QuestionWeight>(_questionWeights);
protected set _questionWeights = value;
protected QuestionScoreTuning()
public class QuestionWeight : DomainBase<long>, IAggregateRoot
public QuestionWeight(Question question, WorkEvaluation evaluation)
Question = question;
WorkEvaluation = evaluation;
public Weight Weight get; set;
public Question Question get; protected set;
public WorkEvaluation WorkEvaluation get; protected set;
public override int GetHashCode()
return (Question.GetHashCode() + "|" + Weight).GetHashCode();
protected QuestionWeight()
Fluent 映射:
public class WorkEvaluationMapping : ClassMap<WorkEvaluation>
public WorkEvaluationMapping()
Id(x => x.ID).GeneratedBy.Identity();
References(x => x.SalaryReview).Not.Nullable();
References(x => x.WorkEvaluationTemplate).Column("WorkEvaluationTemplate_Id").Not.Nullable();
Component(x => x.QuestionScoreTuning, m =>
m.Map(x => x.HitInterval, "HitInterval");
m.HasMany(x => x.QuestionWeights).KeyColumn("WorkEvaluation_id").Cascade.All();
);
public class QuestionWeightMapping : ClassMap<QuestionWeight>
public QuestionWeightMapping()
Not.LazyLoad();
Id(x => x.ID).GeneratedBy.Identity();
Component(x => x.Weight, m =>
m.Map(x => x.Value, "WeightValue");
m.Map(x => x.TypeOfWeight, "WeightType");
);
References(x => x.Question).Column("Question_id").Not.Nullable().UniqueKey(
"One_Weight_Per_Question_And_WorkEvaluation");
References(x => x.WorkEvaluation).Column("WorkEvaluation_id").Not.Nullable().UniqueKey(
"One_Weight_Per_Question_And_WorkEvaluation");
我想要完成的只是将 QuestionWeights 和 HitInterval 的集合移动到值对象(组件映射)中,因为它们仍将位于 db 表 WorkEvaluation 中。
P.S 我查看了一些示例解决方案 DDDSample.net(C# 中的 Eric Evans DDD 示例),他们使用 Itinerary 类实现了这一点,该类将列表作为 ctor 参数并映射为 Cargo 组件。不同之处在于 example 有一个 valueobjects 列表 Leg BUT Leg 引用了 Location ,它是一个实体类。
希望也许有人知道如何做到这一点。提前致谢... /巴切
【问题讨论】:
【参考方案1】:嗯。我终于解决了。现在我的 WorkEvaluation 对象可以与包含权重和命中间隔列表的 QuestionScoreTuning 对象(值对象)一起应用。结果很好,如果有人想了解有关在值对象中包含集合并将它们映射到流利的 NH 中的更多信息,请在此处发表评论。我可以提供代码示例...
【讨论】:
以上是关于Fluent Nhibernate Mapping - 值对象内的一对多?的主要内容,如果未能解决你的问题,请参考以下文章
使用 Fluent NHibernate Auto Mapping 从基实体类映射类型对象的 ID
NHibernate 2 + Fluent Nhibernate 中等信任
NHibernate + Fluent NHibernate 异常
用 Fluent Nhibernate 定义 NHibernate 过滤器的语法?