我在这里有两个相关的表格:
public partial class List
{...
public int RegionId { get; set; }
[ForeignKey("RegionId")]
public virtual Region Region { get; set; }
...}
public partial class Region
{
public Region()
{
Lists = new HashSet<List>();
}
public int RegionId { get; set; }
[Required]
[StringLength(255)]
public string Name { get; set; }
public DateTime Added { get; set; }
public virtual ICollection<List> Lists { get; set; }
}
这里是Regions表的内容:
RegionId Name
1 Global
2 China
3 USA
4 UK
8 Canada
9 Spain
10 France
在微风的一面,我拉下了地区:
var query = new breeze.EntityQuery().from("Regions").select("RegionId,Name").orderBy("RegionId");
return $rootScope.breezeManager.executeQuery(query).then(function (data) {
service.regions = data.results;
似乎有效:
service.regions[2]; // Name: "USA", RegionId: 3
但是,当我尝试创建一个新实体时:
var newList = $rootScope.breezeManager.createEntity('List', listValues);
在listValues中,我指定{ RegionId: 3, ...}
:
newList.RegionId // 3
newList.Region // null
这或许很奇怪,但真的令人沮丧的是,如果我指定另一个值,比如1,它就可以了。同样适用于2和4:
newList.RegionId // 1
newList.Region.Name // "Global"
我一直在仔细研究代码(和互联网)几个小时试图解决这个问题,但是它没有找到我,因此有资格获得我的第一个SO问题!
我现在更加困惑。我计划通过createEntity
调用后手动设置区域来解决此问题,因此我在createEntity
正上方添加了这行代码:
var region = Enumerable.From(service.regions).Single("$.RegionId == " + listValues.RegionId);
然而,在这样做之后,没有其他更改,newList
现在正确地获得了填充Region
,即使是3(美国)!然后我评论了那条线并再次尝试,它仍然有效。尝试过其他几次,各种各样的事情组合,现在它再也没有工作,即使是那条线。不确定这是否有帮助。我会一直在试验。
答案 0 :(得分:1)
我不知道你正在做什么,但我确实看到你有一个根本的误解。
我相信您希望第一个查询返回Region
个实体,并且您认为service.regions
在成功回调中填充了Region
个实体。
两者都不是。您的查询包含select()
clause,这就是我们所说的投影。投影返回数据对象,而非实体。缓存中也没有Region
个实体。
您可能已经在别处看到过 - 也许是Pluralsight视频 - 投影查询确实返回了实体。当查询包含
toType
clause时,会发生这种情况,该{{3}}实际上将投影数据转换为目标类型的实例。这是一个技巧,你应该只是非常谨慎地执行,知道你在做什么,为什么,以及限制。但是你并没有在这个问题中进行投射,所以这个题外话就是重点。
以下service.regions
数组包含一些包含Region
数据的数据对象,但它不包含Region
实体
这也解释了为什么当您使用List
创建新的RegionId:3
实体时,新实体的Region
属性返回null
。当然是null
。仅根据您告诉我们的内容,缓存中根本没有Region
个实体,更不用说ID为3的Region
。
我无法解释您如何获得id = 1或id = 2的Region
。我猜你还有什么东西告诉我们......就像你通过其他一些问题获得这些区域一样。
我不明白为什么你首先使用投影查询。为什么不只是查询所有区域并完成它?
breeze.EntityQuery.from("Regions").orderBy("RegionId")
.using(manager).execute(function(data) {
service.regions = data.results;
});
我根本不了解你的更新;对我来说,这看起来不像是一个有效的EF查询。
首先,为什么要使用HashSet<List>
初始化服务器端Lists
模型类中的Region
属性?这是一种专门的收藏类型,只会让人感到困惑。它没有做到休闲读者可能认为的那样做。虽然它可以阻止某人两次添加相同的对象引用,但它不会阻止某人使用相同的List
添加两个不同的RegionId
对象。要做的简单,明显和正确的事情是......
Lists = new System.Collections.Generic.List<List>();
// the full type name is only necessary because you burned the name "List"
// when defining your model class.
其次,在客户端,请不要用任何方式扩展Angular $rootScope
。这种全球变量&#34;污染&#34;被广泛认为是&#34;不良做法&#34;。将您的Breeze内容保存在适当的Angular服务中,并在需要时注入该服务。