我在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]属性或转换“存档”“返回实体框架可以查询的属性。这纯粹是一个环境足迹问题。