Свободное отображение Nhibernate - один-ко-многим внутри объекта-значения? - PullRequest
0 голосов
/ 07 апреля 2011

Привет, я изо всех сил пытаюсь улучшить / реорганизовать модель предметной области и пытаюсь переместить логику из сервисов приложений в мою модель предметной области.Теперь я застрял с проблемой NHibernate.

Модель представляет собой класс WorkEvaluation, который содержит шаблон вопросника с вопросами, а также коллекцию классов QuestionWeight.Дело в том, что класс WorkEvaluation также имеет важное свойство HitInterval, которое закрыто для коллекции QuestionWeight в WorkEvaluation.Концепция заключается в том, что вы проводите оценку, отвечая на множество вопросов (в этом примере ответы исключены), и, наконец, вы применяете некоторые веса (процентные веса), которые изменяют оценки ответов.Это означает, что вы можете сделать некоторые вопросы более важными, а другие менее важными.Интервал попадания также является параметром настройки, который используется при вычислении итоговой оценки WorkEvaluation (включая изменения веса), и результат, например, такой: Totalscore = 100, Hitinterval 5%, чем мы получаем суммарный интервал 95-105 и может использоваться для соответствиядругие оценки.

Достаточно фона.Я хочу инкапсулировать оба списка 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 в объект Value (сопоставление компонентов), так как онивсе еще будет внутри таблицы базы данных WorkEvaluation.

PS Я рассмотрел пример решения DDDSample.net (пример DDD Эрика Эванса в c #), и они достигли этого с помощью класса Itinerary, который принимает список в качестве параметра ctor иотображается как компонент Cargo.Разница в том, что в этом примере есть список объектов-значений. Leg. НО, Leg имеет ссылки на Location, который является классом сущности.

Надеюсь, может кто-то знает, как это сделать.Заранее спасибо ... / Bacce

1 Ответ

0 голосов
/ 19 апреля 2011

Хорошо.Я наконец решил это.Теперь мой объект WorkEvaluation может быть применен с объектом QuestionScoreTuning (объект value), который содержит список веса и интервал попаданий.Это получается здорово, и если кому-то нужна дополнительная информация о наличии коллекций внутри объектов-значений и отображении их в свободном NH, пожалуйста, спросите здесь с комментарием.Я могу предоставить примеры кода ...

...