流畅的 Nhibernate 映射 - 值对象内的一对多?

发布于 2024-10-30 18:47:14 字数 4502 浏览 2 评论 0原文

您好,我正在努力完善/重构域模型,并尝试将逻辑从应用程序服务转移到我的域模型中。现在我遇到了 NHibernate 问题。

该模型是一个 WorkEvaluation 类,其中包含带有问题的问卷模板,并且还包含 QuestionWeight 类的集合。问题是 WorkEvaluation 类还有一个重要的属性 HitInterval,它属于 WorkEvaluation 中的 QuestionWeight 集合。这个概念是,您通过回答很多问题(本例中排除了答案)来进行评估,最后应用一些权重(百分比权重)来修改答案分数。这意味着您可以使一些问题变得更重要,而另一些问题变得不那么重要。命中间隔也是计算 TOTAL WorkEvaluation 分数(包括权重修改)时使用的调整参数,结果例如:Totalscore = 100,Hitinterval 比我们得到的总间隔 95-105 低 5%,可用于匹配其他评价。

足够的背景。 我想将 QuestionWeights 和 HitInterval 的列表封装在值对象 QuestionScoreTuning 中,因为它们属于一起并且应该同时应用。 我还想在 QuestionScoreTuning 中添加一些不属于 workEvaluation 的业务逻辑。 如何在 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()
    {}
}

流畅的映射:

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 的集合移动到值对象(组件映射)中,因为它们仍然位于数据库表 WorkEvaluation 中。

PS 我查看了一些示例解决方案 DDDSample.net(Eric Evans DDD 在 c# 中的示例),他们使用 Itinerary 类实现了这一点,该类采用列表作为 ctor 参数并映射为 Cargo 组件。不同之处在于该示例具有值对象 Leg 的列表,但 Leg 具有对实体类 Location 的引用。

希望也许有人知道如何实现这一点。提前致谢... /巴塞

Hi I'm struggling do refine/refactoring a domain model and trying to move logic from application services into my domain model. Now I'm stuck with a NHibernate issue.

The model is a WorkEvaluation class that contains a Questionaire Template with Questions and it also contains a collection of QuestionWeight classes. The thing is that WorkEvaluation class also has an important property HitInterval that belongs closed to the QuestionWeight collection in WorkEvaluation. The concept is that you conduct an evaluation by answering a lot of questions (the anserws are excluded in this example) and finaly you apply some weights (percent weights) that modify answer scores. That means you can make some questions more important and other less important. Hit interval is also a tuning parameter that you use when you calculate TOTAL WorkEvaluation score (including weight modifications) and the result is for example: Totalscore = 100, Hitinterval 5% than we get a totalinterval of 95-105 and can be used to match other evaluations.

Enough of background.
I Want to encapsulate both list of QuestionWeights and HitInterval in a Value Object QuestionScoreTuning since these belongs together and should be applied at the same time.
And I also want to add some business logic into QuestionScoreTuning that do not belongs to workEvaluation.
How do I map i Fluent Nhibernate a Value Object (Component) that has the one-to-many collection and HitInterval and the reference back? This is my current code:

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 Mappings:

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");
        }
    }

All I want to accomplish is to move collection of QuestionWeights and HitInterval into a Value Object (Component mapping) since these will still be inside db table WorkEvaluation.

P.S I've look at some example solution DDDSample.net (Eric Evans DDD example in c#) and they accomplished this with the Itinerary class that takes a list as ctor parameter and is mapped as a Cargo component. Difference is that example has a list of valueobjects Leg BUT Leg has references to Location which is an entity class.

Hopefully maybe someone knows how to accomplish this. Thanks in advance...
/Bacce

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

旧时光的容颜 2024-11-06 18:47:14

出色地。我终于解决了。现在,我的 WorkEvaluation 对象可以与包含权重和命中间隔列表的 QuestionScoreTuning 对象(值对象)一起应用。事实证明这很棒,如果有人想了解更多有关在值对象中包含集合并将它们映射到流畅的 NH 的信息,请在此处提问并发表评论。我可以提供代码示例...

Well. I Finally solved it. Now my WorkEvaluation object can be Applied with a QuestionScoreTuning object (a valueobject) that contains the list of weight and hitinterval. This turns out great and if anyone want more info about having collections inside value objects and mapping them in fluent NH, please ask here with a comment. I can supply code examples...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文