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 过滤器的语法?

Fluent NHibernate and Mysql,SQLite

Fluent NHibernate - NHibernate.QueryException:无法解析属性