我想创建一个对象代理,类似于 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 是众所周知的,所以我可以创建一个包含这些字段的对象代理,而其他字段则保留默认代理行为。除了在数据库中找不到此 id 时抛出异常之外,如果预初始化字段不匹配或静默覆盖它们,我可以抛出异常。我将 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
}