如何创建带有一些初始化字段(Id除外)的NHibernate代理对象?
|
我想创建一个对象代理,类似于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
}
没有找到相关结果
已邀请:
3 个回复
青董据零
席酱
。 我唯一想考虑做类似事情的情况是,当我有很多不需要的属性时(在您的示例中,例如Field1..Field20)。 在这种情况下,我要么: 1.将这些属性一起定义为一个组件,或者 2.创建一个DTO,仅获取实体属性的一个子集。
咖哀烈
,
,
,
映射上指定lazy = \“ true \”(或Fluent NHib的Not.LazyLoad())可能会有所帮助,尽管不确定Select N + 1问题。 另一种方法是为
,
指定lazy = \“ false \”