NHibernate проецирует дочерние объекты в родительские свойства с помощью Linq или QueryOver - PullRequest
4 голосов
/ 27 апреля 2011

Может быть, это просто, но я застрял с этим, и я не нашел ответа на вопрос, как это можно сделать.У меня есть родительская сущность User с коллекцией дочерних сущностей Operations.Эти две сущности предназначены только для пользовательского интерфейса, поэтому они являются видом представлений.Вот псевдокод

public class User
{
   public int Id {get; set;}
   public IEnumerable<Operation> Operations {get; set;}
   public int TotalSuccessfulAccesses {get; set;} // not mapped to the database
   public int TotalFailedAccesses {get; set;}     // not mapped to the database
}

public class Operation
{
   public int Id {get; set; }
   public int UserId {get; set; } // FK
   public int NbSuccessfulAccesses {get; set; }
   public int NbFailedAccesses {get; set; }
}

То, что я хотел бы сделать, это чтобы пользователь инициализировался из TotalSuccesfulAccesses и TotalFailedAccesses из дочерней коллекции в одну поездку в базу данных.

Для каждогопользователь должен вычислить Sum (Operation.NbSuccessfulAccesses) и Sum (Operation.NbFailedAccesse) и сделать прогноз соответственно для User.TotalSuccesfulAccesses и пользователя.TotalFailedAccesses .

Я пытался играть с многокритериальными и несколькими запросами, но меня это не устраивает.Я хотел бы знать, если, возможно, есть простой способ сделать это с помощью проекции или что-то другое.Или, может быть, я что-то пропустил.

Что бы вы порекомендовали?

Заранее спасибо за помощь.

Ответы [ 3 ]

4 голосов
/ 04 мая 2011

Мне удалось избавиться от магических строк псевдонимов следующим образом:

UserViewModel userView = null;

Add(Projections.Sum<User>(x => operations.NbSuccessfulAccesses).WithAlias(() => userView.TotalSuccessfulAccesses))
3 голосов
/ 27 апреля 2011

Возможно, вам необходимо разделить модели представлений и сущности вашего домена.Я предполагаю, что в вашем домене у вас есть класс User, имеющий список операций, и эти объекты отображаются соответствующим образом.

Затем вы можете создать модель представления:

public class UserViewModel
{
    public int UserId { get; set; }
    public int TotalSuccessfulAccesses { get; set; }
    public int TotalFailedAccesses {get; set;}
}

Используя ICriteria, вы можетесоздайте следующий запрос:

var criteria = Session.CreateCriteria(typeof(User));
criteria.CreateAlias("Operations", "operations", JoinType.LeftOuterJoin);

var projList = Projections.ProjectionList();

projList.Add(Projections.GroupProperty("Id"));
projList.Add(Projections.Sum("operations.NbSuccessfulAccesses"), "TotalSuccessfulAccesses"); 
projList.Add(Projections.Sum("operations.NbFailedAccesses"), "TotalFailedAccesses");

criteria.SetProjection(projList);
criteria.SetResultTransformer(Transformers.AliasToBean<UserViewModel>());

var ret = criteria.List<UserViewModel>();

Создайте модель представления в соответствии с вашими потребностями и добавьте любые свойства в список проекций соответственно.

Надеюсь, это поможет.

2 голосов
/ 27 апреля 2011

Благодаря Кей, я придумал следующий перевод:

Operation operations = null;
var q = GetSession().QueryOver<User>().Where(u => u.AccessKeyId == accessKeyId)
                    .Left.JoinQueryOver(x => x.Operations, () => operations)
                    .Select(Projections.ProjectionList()
                        .Add(Projections.Sum<User>(x => operations.NbSuccessfulAccesses), "TotalSuccessfulAccesses"))
                        .Add(Projections.Sum<User>(x => operations.NbFailedAccesses), "TotalFailedAccesses"))
                    .TransformUsing(Transformers.AliasToBean<UserViewModel>()).List< UserViewModel >();

Однако я хотел бы знать, есть ли способ избавиться от волшебной строки "TotalSuccessfulAccesses" и "TotalFailedAccesses".

если я использую что-то подобное

UserViewModel userView = null;

Add(Projections.Sum<User>(x => operations.NbSuccessfulAccesses),  () => userView.TotalSuccessfulAccesses)

NHibernate выдает ошибку:

Не удалось найти установщик для свойства 'userView.TotalSuccessfulAccesses'в классе 'Domain.Query.UserViewModel'

, что неверно, поскольку имеется установщик для свойства TotalSuccessfulAccesses.

Есть идеи?

Спасибо

...