2010-08-09 2 views
4

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

[ActiveRecord("INCIDENT")] 
public class Incident : ActiveRecordBase<Incident> 
{ 
    [PrimaryKey(PrimaryKeyType.Native, "INCIDENT_ID", ColumnType = "Int32")] 
    public virtual int IncidentId { get; set; } 

    [Property("CREATION_DATETIME", ColumnType = "DateTime")] 
    public virtual DateTime? CreationDatetime { get; set; } 

    [BelongsTo("CAUSE_CD")] 
    public virtual Cause Cause { get; set; } 
} 

[ActiveRecord("CAUSE")] 
public class Cause : ActiveRecordBase<Cause> 
{ 
    [PrimaryKey(PrimaryKeyType.Native, "CAUSE_CD", ColumnType = "String")] 
    public virtual string CauseCd { get; set; } 

    [Property("CAUSE_DESC", ColumnType = "String", NotNull = true)] 
    public virtual string CauseDesc { get; set; } 
} 

Вот что я использую для запроса базы данных.

DetachedCriteria incidentCriteria = DetachedCriteria.For<Incident>("i") 
.SetProjection(Projections.ProjectionList() 
    .Add(Projections.Property("i.IncidentId")) 
    .Add(Projections.Property("i.CreationDatetime")) 
) 
.SetResultTransformer(Transformers.AliasToBean<Incident>()); 
IList<Incident> incidents = Incident.FindAll(incidentCriteria); 

Оба свойства выступов не заполняются, если я не задал псевдоним. Поэтому мой вопрос: почему дополнительный псевдоним? Я уверен, что просто пропущу что-то еще. Но если я помещу случайный псевдоним (например, abc), он вернет ошибку, заявив, что не может найти свойство abc в классе Incident. Достаточно справедливо, я добавляю соответствующий псевдоним, чтобы соответствовать моим именам свойств. И вуаля! Мои свойства теперь заполняются.

Теперь возникает вопрос, когда я хочу запросить таблицу поиска. Добавить

.Add(Projections.Property("c.CauseDesc"), "CauseDesc") 

к моему ProjectionList и добавить

.CreateCriteria("i.Cause", "c") 

Но теперь он жалуется, что не может найти «CauseDesc» из моей модели инцидентов.

Что я упускаю из-за всего этого испытания?

Update: Следующего код

IList<Incident> results = sess.CreateCriteria<Incident>("i") 
    .SetProjection(Projections.ProjectionList() 
     .Add(Projections.Property("i.IncidentId"), "IncidentId") 
     .Add(Projections.Property("i.CreationDatetime"), "CreationDatetime") 
     .Add(Projections.Property("c.CauseDesc"), "CauseDesc") 
    ) 
    .Add(Expression.Gt("i.IncidentId", 1234567)) 
    .CreateAlias("Cause", "c") 
    .List<Incident>(); 

Это действительно создает недопустимый запрос (я проверил это с профайлерами), но это, кажется, возникают проблемы, населяющие мой общий список. Это дает мне ошибку «Значение». System.Object [] \ "не относится к типу \" oms_dal.Models.Incident \ "и не может использоваться в этой общей коллекции. \ R \ nParameter name: value". Тем не менее, все работает нормально, если я не использую проекцию, но затем выбирает 50 полей, которые я не хочу. Означает ли это, что я вынужден использовать DTO в этом случае?

ответ

5

Вы должны указать имя свойства проекции, как ...

.Add(Projections.Property("i.IncidentId"), "IncidentId") 

также, в общем, вы не проецировать на тот же объект домена. Вы должны создать инцидент DTO как ...

public class IncidentDTO 
{ 
    public int IncidentID { get; set; } 
    public DateTime CreationDatetime { get; set; } 
} 

, а затем ...

.SetProjection(Projections.ProjectionList() 
    .Add(Projections.Property("i.IncidentId"), "IncidentId") 
    .Add(Projections.Property("i.CreationDatetime"), "CreationDatetime") 
) 
.SetResultTransformer(Transformers.AliasToBean<IncidentDTO>()); 

Если вы хотите Инциденты соответствие определенным критериям (не DTO), то не установленные проекции/resulttransformer , Вместо этого вы просто делаете что-то вроде этого ...

IList<Incident> incidents = session.CreateCriteria<Incident>() 
    .CreateAlias("Cause", "c") //now you can access Cause properties via `c.` 
    .Add(Restrictions.Eq("c.CauseDesc", "some cause")) 
    .List<Incident>(); 

Посмотрите, как объект критериев корня не нуждается в псевдониме. Если это помогает, я использую только CreateCriteria для исходного объекта. Если мне нужно ссылаться на дочерние объекты, я использую CreateAlias.

+0

О вашем последнем примере, я продолжаю получать ошибку «Значение». System.Object [] \ "не относится к типу \" oms_dal.Models.Incident \ "и не может использоваться в этой общей коллекции. \ R \ nParameter name: value ", когда я устанавливаю проекцию. Посмотрите мой обновленный ответ. – Mike

+0

Да, если вы установите проекцию, вы должны использовать DTO.Прогнозы НЕ используются для управления загрузкой свойств в объекте домена. Они используются для представления данных в DTO для отображения. – dotjoe

+0

Спасибо! Теперь Waayy яснее. :) – Mike