0

こんにちは私はエンティティとクエリをキャッシュするように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の第2レベルのキャッシュにも保存する方法はありますか?

4

1 に答える 1

0

NHibernateはエンティティ全体を第2レベルのキャッシュにキャッシュしません。マップされたプロパティからの状態/データのみをキャッシュします。あなたはここでそれについてもっと読むことができます:http://ayende.com/blog/3112/nhibernate-and-the-second-level-cache-tips

その投稿のコメントには、これをもう少し詳しく説明する興味深い議論があります。

Frans Bouma: オブジェクトはシリアル化可能である必要がありますね。複数のアプリドメインについて話しているので。何がより効率的か疑問に思います。dbサーバーのキャッシュに依存するか、シリアル化レイヤーを使用してオブジェクトを前後に転送します。

Ayende Rahien: いいえ、彼らはそれを必要としません。これは、NHibernateがエンティティをキャッシュに保存しないためです。そうすることで、競合状態に陥ることがあります。NHibernateは、エンティティデータのみを保存します。これは通常、プリミティブデータで構成されます(結局、DBが保存できるデータです)。一般に、キャッシュサーバーは非常に簡単に高度に拡張可能であり、I / Oが含まれないため、キャッシュサーバーにアクセスする方が効率的です。

于 2012-06-13T14:44:33.063 に答える