2010-08-09 42 views
4

我在阅读关于DetachedCriteria的documentation。文档清楚地显示为您的投影设置别名是可选的。但是,每当我省略别名时,我的模型属性都不包含数据。这是我的两个测试模型。为什么我需要为我的投影设置别名(如果它是可选的)?

[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”。公平的,我添加适当的别名来匹配我的属性名称。瞧!我的物业现在正在填充物业。

现在出现了我想查询查询表的问题。我想补充

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

我ProjectionList和追加

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

但现在抱怨说,它无法从我的事件模型中找到“CauseDesc”。

我从这整个标准考验中错过了什么?

更新: 下面的代码

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>(); 

这不会创建一个有效的查询(我有一个分析器检查的话),但它似乎有填充我的泛型列表的问题。它给了我错误“The value \”System.Object [] \“不是\”oms_dal.Models.Incident \“的类型,并且不能在此泛型集合中使用。\ r \ nParameter name:value”。然而,如果我不使用投影,但是它会选择50个我不想要的字段,所有工作都很好。这是否意味着我在这种情况下被迫使用DTO?

回答

5

您还需要指定投影属性名状...

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

,一般你不伸入同一个域中的对象。如果你想事件满足某种条件(不是DTO),那么就不要设置预测你应该创建一个事件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>()); 

/使用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

关于你的最后一个例子,我不断收到错误“The value \”System.Object [] \“不是\”oms_dal.Models.Incident \“的类型,并且不能在这个泛型集合中使用。\ r \ nParameter名称:值“当我设置投影。请看我更新的答案。 – Mike 2010-08-10 13:53:29

+0

是的,如果您设置投影,您必须使用DTO。投影不用于控制域对象中属性的加载。它们用于将数据投影到DTO中以进行显示。 – dotjoe 2010-08-10 14:10:08

+0

谢谢! Waayy现在更清楚了。 :) – Mike 2010-08-10 14:47:26

相关问题