我可以在NHibernates二级缓存中缓存具有非映射属性的实体吗?

时间:2012-06-13 11:46:26

标签: nhibernate caching active-directory entity

您好我已经设置了SessionFactory来缓存实体和查询:

private ISessionFactory CreateSessionFactory()
{
    var cfg = new Configuration().Proxy(
        properties => properties.ProxyFactoryFactory<DefaultProxyFactoryFactory>()).DataBaseIntegration(
            properties =>
            {
                properties.Driver<SqlClientDriver>();
                properties.ConnectionStringName = this.namedConnection;
                properties.Dialect<MsSql2005Dialect>();
            }).AddAssembly(this.resourceAssembly).Cache(
                properties =>
                {
                    properties.UseQueryCache = true;
                    properties.Provider<SysCacheProvider>();
                    properties.DefaultExpiration = 3600;
                });
    cfg.AddMapping(this.DomainMapping);

    new SchemaUpdate(cfg).Execute(true, true);
    return cfg.BuildSessionFactory();
}

这是我的用户映射

public class UserMapping : EntityMapping<Guid, User>
{
    public UserMapping()
    {
        this.Table("USERS");
        this.Property(
            x => x.CorpId,
            mapper => mapper.Column(
                c =>
                {
                    c.Name("CorporateId");
                    c.UniqueKey("UKUserCorporateId");
                    c.NotNullable(true);
                }));
        this.Set(
            x => x.Desks,
            mapper =>
            {
                mapper.Table("DESKS2USERS");
                mapper.Key(km => km.Column("UserId"));
                mapper.Inverse(false);
                mapper.Cascade(Cascade.All | Cascade.DeleteOrphans | Cascade.Remove);
            },
            rel => rel.ManyToMany(mapper => mapper.Column("DeskId")));
        this.Cache(
            mapper =>
            {
                mapper.Usage(CacheUsage.ReadWrite);
                mapper.Include(CacheInclude.All);
            });
    }
}

我想要做的是获取用户或查询一些用户并向域对象添加信息并缓存更新的对象。

public class User : Entity<Guid>, IUser
{
    public virtual string CorpId { get; set; }

    public virtual ISet<Desk> Desks { get; set; }

    public virtual MailAddress EmailAddress { get; set; }

    public virtual string Name
    {
        get
        {
            return string.Format(CultureInfo.CurrentCulture, "{0}, {1}", this.SurName, this.GivenName);
        }
    }

    public virtual string GivenName { get; set; }

    public virtual string SurName { get; set; }
}

类似的东西:

var users = this.session.Query<User>().Cacheable().ToList();

if (users.Any(user => user.EmailAddress == null))
{
    UserEditor.UpdateThroughActiveDirectoryData(users);
}

return this.View(new UserViewModel { Users = users.OrderBy(entity => entity.Name) });

或者这个:

var user = this.session.Get<User>(id);

if (user.EmailAddress == null)
{
    UserEditor.UpdateThroughActiveDirectoryData(user);
}

return this.View(user);

UpdateThroughActiveDirectory方法可以工作,但每次从缓存中获取数据时都会执行,更新的实体不会保留其他数据。有没有办法将这些数据存储在nhibernates二级缓存中?

1 个答案:

答案 0 :(得分:0)

NHibernate不会将整个实体缓存在二级缓存中。它仅缓存映射属性中的状态/数据。您可以在此处详细了解:http://ayende.com/blog/3112/nhibernate-and-the-second-level-cache-tips

在该帖子的评论中有一个有趣的讨论,进一步解释了这一点:

  

Frans Bouma:对象需要序列化,不是吗?我们正在谈论多个appdomains。我想知道还有什么   高效:依赖数据库服务器的缓存或传输   使用序列化层来回传递对象。

     

Ayende Rahien:不,他们不需要那样。这是因为NHibernate不会将实体保存在缓存中。这样做会打开   你要竞争条件。 NHibernate单独保存实体数据,   它通常由原始数据组成(这就是数据库所能做到的)   毕竟商店)。通常,命中缓存更有效   服务器,因为它们很容易扩展到高度,并且   没有涉及的I / O.