如何创建带有一些初始化字段(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 
        }
    
已邀请:
        您可以在查询中指定一个急切的访存,以实际检索所需的关联。根据您使用的查询样式(Criteria,Hql或LINQto NH),可以通过不同的方式完成此操作。但是关键是改变获取模式。     
        对于非集合属性,我不会这样做; 通常,在加载实体时从数据库预取它们的成本很小,以至于我什至都不会打扰。 对于集合属性,只需将集合获取策略标记为
\'lazy=true\'
。 我唯一想考虑做类似事情的情况是,当我有很多不需要的属性时(在您的示例中,例如Field1..Field20)。 在这种情况下,我要么: 1.将这些属性一起定义为一个组件,或者 2.创建一个DTO,仅获取实体属性的一个子集。     
        在属性
Field1
Field2
Field3
Comments
映射上指定lazy = \“ true \”(或Fluent NHib的Not.LazyLoad())可能会有所帮助,尽管不确定Select N + 1问题。 另一种方法是为
UserName
Email
指定lazy = \“ false \”     

要回复问题请先登录注册