nhibernate - sproutcore: как получить только ссылочные идентификаторы и не загружать ссылку / отношение? - PullRequest
2 голосов
/ 11 октября 2010

Я использую в качестве внешнего интерфейса sproutcore, а в качестве внутреннего - решение REST openrasta с управляемым nhibernate.

В sproutcore ссылки являются фактически идентификаторами / guid. Таким образом, сущность Address в модели 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 = [<code></p> <p><code> { guid: "1",

street: "MyHomeStreet",

houseNumber: "34",

city: "6" }

]

Здесь вы видите, что эталонный город имеет значение 6. Когда в какой-то момент вашей программы вы хотите использовать эту эталонную ссылку, это делается с помощью: myAddress.Get ( "город"). MyCityName

Итак, Sproutcore автоматически использует предоставленный идентификатор в REST Get и извлекает необходимую запись. Если запись доступна в локальной памяти клиента (ранее загруженной), то на сервер не выполняется обратная передача, в противном случае для этого идентификатора выполняется http get: «http://servername/city/6". Очень приятно.

Nhibernate (отображается с использованием Fluent-Nhibernate):

public AddressMap() { Schema(Config.ConfigElement("nh_default_schema", "Funda"));</p> <pre><code> 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» в таблице базы данных. Работает нормально. НО (а это мои вопросы к гуру):

  1. Вы можете указать для ленивой загрузки / нетерпеливой загрузки ссылки (город). Конечно, вы не хотите загружать все ваши ссылки. ТАК вообще ваша привязка к ленивой загрузке. Но когда Openrast (или WCF или ...) сериализует такой объект, он выполняет итерацию свойств, что вызывает запуск всех методов get свойств, что приводит к отложенной загрузке всех ссылок.

ТАК, если ваша сущность имеет 5 ссылок, 1 запрос для базового объекта и 5 для ссылок. Вы могли бы быть лучше с нетерпеливой загрузкой тогда .... Это отстой ... Или я не прав?

  1. Поскольку я показал, как работает модель внутри sproutcore, мне нужны только идентификаторы ссылок. Так что я не хочу eagerloading, а также не ленивая загрузка. просто "Получить * из адреса, где ID =%" и получить это сопоставлено с моей сущностью адреса Тогда у меня также есть идентификаторы ссылок, что радует Sproutcore и меня (без загрузки ненужных ссылок). Но .... может ли NHibernate отобразить только идентификаторы ссылок? И могу ли я позже указать nHibernate, чтобы полностью загрузить ссылку?

Одним из подходов может быть (но это не самый удачный) загрузка всех ссылочных EAGER (с объединением) (что за пустая трата ресурсов ... я знаю) и в моем объекте адреса стороны сервера:

</p> <pre><code> // 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, но с другой стороны все ссылки загружены. Лучшая идея для меня ???

  1. NHibernate к LINQ

3a. Я хочу получить свой адрес без ссылок (но желательно с их идентификаторами)

Dao myDao = новый Dao (); из р в myDao.All () выберите p;

Если в моем отображении загружаются ленивые города, как я могу указать в запросе linq, что я хочу, чтобы он также включал только мой идентификатор города?

3б.

Я хочу получить адреса с моими городами, загруженными в 1 запросе: (которые отображаются как lazyloaded)

Dao myDao = новый Dao (); из р в myDao.All () присоединиться к p.city ??????? выберите p;

  1. Мой главный вопрос: Как говорилось ранее, при отложенной загрузке все ссылки загружаются при сериализации объектов. Как я могу предотвратить это и только более эффективно получать идентификаторы ссылок?

Большое спасибо за чтение, и, надеюсь, вы сможете помочь мне и другим с теми же вопросами. С уважением.

1 Ответ

0 голосов
/ 05 марта 2012

как записку, которую вы написали, вы делаете это

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, когда я действительно хочу объекты. Часть этого подхода заключается в том, что у меня очень легкий источник данных - я в основном спасаюсь от всех методов create / update / fetch в зависимости от того, что обрабатывает мой уровень API. Я использую pushRetrieve и связанные методы для обновления магазина.

Я делаю это, потому что магазин очень жестко использует источники данных. Мне нравится больше гибкости; не все серверные API работают одинаково.

...