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

我在breeze中未映射的属性似乎不适用于投影,breeze,Breeze,我拥有以下实体: public class Invoice { [Key] public int Id { get; set; } public DateTime? ArchiveDate { get; set; } public DateTime? ClotureDate { get; set; } ... } 我想知道我的发票是使用某种标志(布尔值)存档还是关闭的。为此,我在breeze实体中添加了2个未映射的属性,如下所示: public clas

我拥有以下实体:

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; } } 
    ...
}
var query = entityQuery.from("Invoices")
                       .where('id', '==', id)
                       .toType('Invoice');
现在我可以像这样查询我的breeze实体:

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');
上述调用将返回我的发票实体的所有属性(包括已存档和已冻结)。它工作得很好

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

var query = entityQuery.from("Invoices")
                       .where('id', '==', id)
                       .select("id, archived, clotured")
                       .toType('Invoice');
我收到错误:指定的类型成员“存档”在LINQ to实体中不受支持。仅支持初始值设定项、实体成员和实体导航属性。

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

或者有人有别的解决办法吗

非常感谢。

从查询中删除“.toType('Invoice')”行。只需执行以下操作:

 var query = entityQuery.from("Invoices")
                   .where('id', '==', id)
                   .select("id, archived, clotured");
这将迫使breeze将您的投影强制为发票实体类型。如果您不使用该选项,您将得到一个真正的投影,即一个纯javascript对象,仅包含您指定的属性,即不是实体。

Short version 您看到的是完全可以预料的。
ArchivedDate
既是一个持久化的数据属性,也是一个序列化的属性。
Archived
属性不是持久化的,而是序列化的。这就是为什么可以同时看到
ArchivedDate
Archived
的数据值。但是,远程query…在服务器上执行的LINQ查询…可能只引用持久化属性,如
ArchivedDate
。EF对计算属性(如
Archived
)一无所知;它们不能参与LINQ查询…不能参与
where
select
orderBy
或任何其他查询。您不能在查询中提及EF不知道的内容…您告诉EF(正确地)忽略这些
已存档的
已冻结的
计算属性

长版本 [Unmapped]属性对EF隐藏属性…这是必须的,因为
Archived
cloted
是计算属性,而不是持久数据

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

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

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

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


<代码> toType 是一个红色鲱鱼,它与此无关。

从错误中可以清楚地看到,您在对象上创建了一个不属于该实体属性的附加属性,因此不能使用LINQ对该属性进行实体查询。解决方案,我不必在数据库中保留此信息,因为这与相应的日期是多余的。我按照您的建议进行了尝试:删除
。toType('Invoice')
,但我仍然遇到问题中提到的错误!?好的,在这种情况下,您需要删除[NotMapping]属性或转换“存档”“返回实体框架可以查询的属性。这纯粹是一个环境足迹问题。