我有以下实体:
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'。仅支持初始值设定项,实体成员和实体导航属性。
非常令人沮丧。知道为什么我不能执行这样的查询吗?
或许某人有另一种解决方案?
非常感谢。
答案 0 :(得分:2)
您所看到的是完美的预期。 ArchivedDate
既是持久数据属性又是序列化属性。 Archived
属性不会保留,但会被序列化。这就是为什么你看到1}}和ArchivedDate
的数据值的原因。但是,远程查询 ...在服务器上执行的LINQ查询...可能只引用Archived
等持久性属性。 EF对ArchivedDate
等计算属性一无所知;他们无法参与LINQ查询...不在Archived
,where
,select
或任何其他查询中。您不能在EF不知道的查询中提及某些内容......并且您告诉EF(正确)忽略这些orderBy
和Archived
计算的属性。
[Unmapped]属性隐藏EF中的属性......因为它必须是Clotured
和Archived
是计算属性,而不是可持久数据。
[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对象,即不是实体。