nhibernate - sproutcore:如何只检索参考 ID 而不加载参考/关系?
Posted
技术标签:
【中文标题】nhibernate - sproutcore:如何只检索参考 ID 而不加载参考/关系?【英文标题】:nhibernate - sproutcore : How to only retrieve reference ID's and not load the reference/relation? 【发布时间】:2010-10-11 09:21:58 【问题描述】:我使用作为前端的 sproutcore,作为后端使用 nhibernate 驱动的 openrasta REST 解决方案。
在sproutcore 中,引用实际上是ID/guid。因此,Sproutcore 模型中的地址实体可能是:
// sproutcore code
App.Address = App.Base.extend(
street: SC.Record.attr(String, defaultValue: "" ),
houseNumber: SC.Record.attr(String),
city: SC.Record.toOne('Funda.City')
);
有测试数据:
Funda.Address.FIXTURES = [
guid: "1",
street: "MyHomeStreet",
houseNumber: "34",
city: "6"
]
在这里,您看到参考城市的值为 6。当您在程序中的某个时刻想要使用该参考时,可以通过以下方式完成: myAddress.Get("city").MyCityName
因此,Sproutcore 会自动在 REST Get 中使用提供的 ID,并检索所需的记录。如果记录在客户端的本地内存中可用(之前已加载),则不会对服务器进行往返,否则会对该 ID 进行 http get:“http://servername/city/6”。很不错。
Nhibernate(使用 fluent-nhibernate 映射):
public AddressMap()
Schema(Config.ConfigElement("nh_default_schema", "Funda"));
Not.LazyLoad();
//Cache.ReadWrite();
Id(x => x.guid).Unique().GeneratedBy.Identity();
Table("Address");
Map(x => x.street);
Map(x => x.houseNumber);
References(x => x.city,
"cityID").LazyLoad().ForeignKey("fk_Address_cityID_City_guid");
这里我指定了外键,并将“cityID”映射到数据库表上。它工作正常。 但是(这些是我对大师的问题):
-
您可以指定延迟加载/急切加载引用(城市)。当然,您不想急切地加载所有参考资料。所以通常你与延迟加载有关。
但是当 Openrast(或 WCF 或 ...)序列化这样的对象时,它会迭代属性,这会导致属性的所有 get 被触发,这会导致所有引用都被延迟加载。
所以如果您的实体有 5 个引用,1 个基本对象查询和 5 个引用将被完成。那么你最好不要急于加载...... 这太糟糕了......还是我错了?
-
当我展示了 sproutcore 中的模型如何工作时,我只想要引用的 ID。所以我不想急切加载,也不想延迟加载。
只是一个“从 ID = % 的地址获取 *”并将其映射到我的地址实体。
那么我也有让 Sproutcore 和我高兴的参考 ID(不加载不需要的参考)。但是.... NHibernate 可以仅映射引用的 ID 吗?
我以后可以指示 nHibernate 完全加载引用吗?
一种方法可能是(但不是一个好方法)加载所有引用 EAGER(加入)(多么浪费资源……我知道)并在我的服务器端地址实体中:
// Note: NOT mapped as Datamember, is NOT serialized!
public virtual City city get; set;
Int32 _cityID;
[Datamember]
public virtual Int32 cityID
get
if (city != null)
return city .guid;
else
return _cityID;
set
if (city!= null && city.guid != value)
city= null;
_cityID = value;
else if (city == null)
_cityID = value;
所以我获得了 Sproutcore 的 ID 属性,但不利的一面是,所有引用都已加载。 对我来说更好的主意???
-
nHibernate-to-linq
3a。我想在没有他们的参考资料的情况下获得我的地址(但最好有他们的 id)
道 myDao = new Dao(); 来自 myDao.All() 中的 p 选择 p;
如果城市在我的映射中延迟加载,我如何在 linq 查询中指定我希望它也只包含我的城市 ID?
3b.
我想获取我的城市在 1 个查询中加载的地址:(映射为延迟加载)
道 myDao = new Dao(); 来自 myDao.All() 中的 p 加入p.city ??????? 选择 p;
-
我的主要问题:
如前所述,通过延迟加载,在序列化实体时所有引用都是延迟加载的。我怎样才能防止这种情况,并且只能以更有效的方式获取参考 ID?
非常感谢您的阅读,希望您能帮助我和其他有相同问题的人。亲切的问候。
【问题讨论】:
【参考方案1】:作为你写的笔记,你这样做
myAddress.Get("city").MyCityName
应该是什么时候
myAddress.get("city").get("MyCityName")
或
myAddress.getPath("city.MyCityName")
除此之外,我认为您的问题是“我要如何才能不加载城市对象?”。
假设您正在使用数据源,当您请求城市对象时,您需要在数据源中进行管理。因此,在您的数据源中的retrieveRecord
中根本不触发请求,并使用适当的参数调用dataSourceDidComplete
(查看datasource.js 文件),因此城市记录不在BUSY
状态。您基本上是在告诉商店记录已加载,但您传递了一个空哈希,因此该记录没有数据。
当然,问题在于您有时需要检索记录。您可以定义一个像App.WANTS_CITY
这样的全局变量,并且在retrieveRecords
中仅在您需要城市时进行检索。您需要管理该触发器的值;状态图是执行此操作的好地方。
您问题的另一部分是“我如何一次加载一堆记录,而不是每条记录一个请求?”
注意数据源有一个方法retrieveRecords
。您可以为该方法定义自己的实现,这将允许您获取所需的任何记录——这避免了对 N 个子记录的 N 次请求——你可以在一个请求中完成所有这些。
最后,就我个人而言,我倾向于使用诸如
之类的方法编写 API 层getAddress
和
getCity
并在我真正需要对象时适当地调用我的 API。这种方法的一部分是我有一个非常轻量级的数据源——我基本上摆脱了所有创建/更新/获取方法,具体取决于我的 API 层处理的内容。我使用pushRetrieve
和相关方法来更新商店。
我这样做是因为商店以非常严格的方式在数据源中使用。我喜欢更多的灵活性;并非所有服务器 API 都以相同的方式工作。
【讨论】:
以上是关于nhibernate - sproutcore:如何只检索参考 ID 而不加载参考/关系?的主要内容,如果未能解决你的问题,请参考以下文章