0

我有以下实体:

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

我想知道我的发票是使用一种标志(布尔值)存档还是关闭。为此,我在我的微风实体中添加了 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; } } 
    ...
}

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

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

上面的调用将返回我的发票实体的所有属性(包括归档和 clotured)。它运作良好。

但我只需要一些特定的属性(用于性能)。然后我尝试:

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

我收到错误消息:LINQ to Entities 不支持指定的类型成员“存档”。仅支持初始化程序、实体成员和实体导航属性。

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

或者也许有人有其他解决方案?

非常感谢。

4

2 回答 2

2

精简版

您所看到的完全符合预期。ArchivedDate既是持久数据属性又是序列化属性。该Archived属性未持久化,但已序列化。这就是您看到ArchivedDate和的数据值的原因Archived。但是,您的远程查询...在服务器上执行的 LINQ 查询...可能仅引用持久化的属性,例如ArchivedDate. EF 对计算的属性一无所知,例如Archived; 他们不能参与 LINQ 查询……不能参与where,selectorderBy任何其他查询。您不能在查询中提及 EF 不知道的某些内容……并且您告诉 EF(正确地)忽略这些ArchivedClotured计算的属性。

长版

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

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

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

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

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

toType是一个红鲱鱼,与此事无关。

于 2013-11-01T06:35:29.843 回答
0

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

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

这迫使微风将您的投影强制转换为 Invoice 实体类型。如果您不使用它,您将得到一个真正的投影,即一个仅具有您指定的属性的纯 JavaScript 对象,即不是一个实体。

于 2013-10-31T16:50:00.070 回答