Я хочу создать объектный прокси, аналогичный тому, что возвращает ISession.Load, но с инициализацией некоторых полей.Для других свойств при доступе прокси извлекает весь объект из базы данных.Рассмотрим следующий пример:
public class User
{
protected User() {
}
public User(int id, string username, string email) {
// ...
}
// initialize the following fields from other datasources
public virtual int Id { get; set; }
public virtual string UserName { get; set; }
public virtual string Email { get; set; }
// the rest of fields when accessed will trigger a select by id in the database
public virtual string Field1 { get; set; }
public virtual string Field2 { get; set; }
public virtual DateTime Field3 { get; set; }
public virtual ISet<Comment> Comments { get; set; }
}
Id, UserName, Email хорошо известны в моем случае, поэтому я мог бы создать прокси-сервер объекта, содержащий эти поля, а для других оставить поведение прокси-сервера по умолчанию.В дополнение к выбрасыванию исключения, если этот идентификатор не найден в базе данных, я мог бы выдать исключение, если предварительно инициализированные поля не совпадают или перезаписывают их молча.Я использую NHibernate.ByteCode.Castle для прокси-фабрик.
Редактировать: Цель этого состоит в том, чтобы иметь возможность иметь некоторые свойства проекции от объекта, к которым можно обращаться в другом месте (например, с индексом lucene), и избегать вызовов базы данных.Затем вместо того, чтобы оборачивать эти поля в пользовательский класс компонентов, содержащий только эти подмножества свойств, я хочу использовать прокси-объект напрямую, чтобы при необходимости я мог загрузить остальные поля.В лучшем случае я бы вообще не попал в базу данных, но в некоторых угловых случаях мне бы хотелось получить доступ и к другим полям.Влияние проблемы SELECT N + 1 может быть значительно уменьшено с помощью пакетной обработки.Гипотетическая версия кода, которую я хочу использовать, будет выглядеть так:
// create User object proxy with some fields initialized
var user = Session.Load<User>(5, new { UserName = "admin", Email = "admin@company.com" });
Console.WriteLine(user.Id); // doesn't hit the database
Console.WriteLine(user.UserName); // doesn't hit the database
Console.WriteLine(user.FullName); // doesn't hit the database
if (somecondition) {
Console.WriteLine(user.Field1); // fetches all other fields
}