我在微风中的未映射属性似乎不适用于投影

时间:2013-10-31 16:21:26

标签: breeze

我有以下实体:

public class Invoice
{
    [Key]
    public int Id { get; set; }
    public DateTime? ArchiveDate { get; set; }
    public DateTime? ClotureDate { get; set; }
    ...
}

我想知道我的发票是使用一种标志(布尔值)存档还是关闭。为此,我在我的breeze实体中添加了2个未映射的属性,如下所示:

public class Invoice
{
    [Key]
    public int Id { get; set; }
    public DateTime? ArchiveDate { get; set; }
    public DateTime? ClotureDate { get; set; }
    [NotMapped]
    public bool Archived { get { return ArchiveDate.HasValue; } } 
    [NotMapped]
    public bool Clotured { get { return ClotureDate.HasValue; } } 
    ...
}

现在我可以像这样查询我的breeze实体:

var query = entityQuery.from("Invoices")
                       .where('id', '==', id)
                       .toType('Invoice');

上述调用将返回我的发票实体的所有属性(包括已存档和已克隆)。效果很好。

但我只需要几个特定的​​属性(性能)。然后我尝试:

var query = entityQuery.from("Invoices")
                       .where('id', '==', id)
                       .select("id, archived, clotured")
                       .toType('Invoice');

我收到错误: LINQ to Entities不支持指定的类型成员'Archived'。仅支持初始值设定项,实体成员和实体导航属性。

非常令人沮丧。知道为什么我不能执行这样的查询吗?

或许某人有另一种解决方案?

非常感谢。

2 个答案:

答案 0 :(得分:2)

短版

您所看到的是完美的预期。 ArchivedDate既是持久数据属性又是序列化属性。 Archived属性不会保留,但会被序列化。这就是为什么你看到ArchivedDate的数据值的原因。但是,远程查询 ...在服务器上执行的LINQ查询...可能只引用Archived等持久性属性。 EF对ArchivedDate等计算属性一无所知;他们无法参与LINQ查询...不在Archivedwhereselect或任何其他查询中。您不能在EF不知道的查询中提及某些内容......并且您告诉EF(正确)忽略这些orderByArchived计算的属性。

长版

[Unmapped]属性隐藏EF中的属性......因为它必须是CloturedArchived是计算属性,而不是可持久数据。

[Unmapped]属性还会从EF生成的元数据中隐藏这些属性。这也是预期和良好的。

但这也意味着您无法构造引用这些属性的LINQ查询。它们不是数据属性。 EF无法查询它们。只有数据属性和导航属性才能出现在LINQ查询中。这真的很简单。

也许您想知道为什么未映射的计算属性值实际传达给JavaScript客户端,为什么这些值出现在JSON有效负载中,如果您将这些属性添加到客户端元数据中,则会填充类似命名的Breeze实体属性Clotured为“未映射的属性”。

要了解原因,您必须了解使用EF查询的属性与使用Json.NET序列化的属性之间的区别。在EF查询完成之后,具体化实体具有数据属性(例如,ArchivedDate)和计算的属性(Archived)。 [NotMapped]属性不会隐藏Json.NET中的属性。 Json.NET序列化物化对象的所有属性 - 数据和计算属性 - 除非你告诉它不要。例如,您可以使用[Ignore]属性从Json.NET序列化中隐藏Archived属性。

Invoice是一只红鲱鱼,与此事无关。

答案 1 :(得分:0)

从查询中删除“.toType('Invoice')'行。只需使用:

 var query = entityQuery.from("Invoices")
                   .where('id', '==', id)
                   .select("id, archived, clotured");

这会强制微风将您的投影强制转换为Invoice实体类型。如果你把它关掉,你会得到一个真正的投影,即只有你指定的属性的普通javascript对象,即不是实体。