2

次のようなクラスモデルがあります。

public class TheSystem 
{
    public virtual Guid Id { get; protected set; }
    public virtual ICollection<User> Users { get; protected set; }
}

public class User
{
    public virtual Guid Id { get; protected set; }
    public virtual string Username { get; set; }
    ...
}

マッピング

public class TheSystemMap : ClassMap<TheSystem>
{
    public TheSystemMap()
    {
        Id(x => x.Id).GeneratedBy.GuidComb();
        HasMany(x => x.Users).Cascade.AllDeleteOrphan().ExtraLazyLoad().Cache.ReadWrite().IncludeNonLazy();

        Cache.ReadOnly();
    }
}

public class UserMap : ClassMap<User>
{
    public UserMap()
    {
        Id(x => x.Id).GeneratedBy.GuidComb();
        Map(x => x.Username).Not.Nullable();
        ...

        Cache.ReadOnly();
    }
}

システムに新しいユーザーを追加したいときに問題が発生します。コレクションを参照しているためUsers、NHibernate はすべてのインスタンスをロードします (1 人のユーザーを挿入したいだけなので、これは望ましくありません)。

...
theSystem.Users.Add(new User("aUser"));
...

ExtraLazyLoad()アイテムの数を取得しようとすると、オプションは期待どおりに機能します (次のコードは、数のみを照会するために生成されます)

...
var count = theSystem.Users.Count;
...

.AsBag()同じ結果でオプションを追加しようとしました。

マッピングに欠けているものがありますか、それとも通常の方法では解決できない状況ですか?

4

2 に答える 2

2

このようなモデルを実行している場合、有効な操作のみを実行できるようにコンシューマーを制約する API サーフェスが必要になる可能性があります。これを行うとき、通常、エンティティの完全な公開不変性を強制します。あらゆる種類の状態を変更するすべての公開操作は、検証およびチェックできる有効なビジネス アクションをモデル化するメソッドまたはオブジェクトによって媒介されます。次に、制約の少ない内部 API があり、永続化メカニズムへの直接アクセスがこのレベルで利用可能です。

このモデルでは、コレクションはパブリック API サーフェスで公開IEnumerable<T>され、基になるフィールドにマップされます。関連する制御エンティティにメソッドを追加して、子オブジェクトを作成/追加および削除します (もちろん、これが有効なドメイン操作である場合)。何かのようなもの

theSystem.AddUser(user);

theSystem.RemoveUser(user);

実際のところ、私のaddメソッドはおそらく次のようになります

theSystem.AddUser(email, password, confirmPassword, firstName, lastName)

API コンシューマーが永続化されたエンティティを直接構築することを許可していないためです。このAddUserメソッドは、ユーザーを構築し、それをセッションに保存して、Users コレクションに追加します。または、カスケードがある場合 (私は通常これを避けます)、それをコレクションに追加します。

(もちろん、DI ではうまく機能しませんが、ここで構築しているような API ではありません。DI が行われている場合は、下位で発生します。)

于 2014-05-06T15:23:07.303 に答える
1

新しいユーザーを作成するだけで、TheSystemすべてを回避できます。

User newUser = new User();
session.Save(newUser);
于 2014-05-02T17:05:45.520 に答える