0

親子関係があり、現在、各子から親への参照のみが存在します(子テーブルに外部キー列があります)。読み取り専用の IEnumerable プロパティを親に追加したいのですが、そうできません。

public class ProjectData : Entity
{
    public virtual long Id {get;set;}
    private readonly IList<BranchData> _branches = new List<BranchData>();
    public virtual IEnumerable<BranchData> Branches
    {
        get { return _branches.AsReadOnly(); }
    }
}

public class BranchData : Entity
{ 
    puplic virtual long Id {get;set;}
    public virtual ProjectData ProjectData { get; set; }
}

 public class BranchDataMapping : ClassMapping<BranchData>
{
    public BranchDataMapping()
    {
       ManyToOne(x => x.ProjectData, mapper => { });
    }
}

  public class ProjectDataMapping : ClassMapping<ProjectData>
{
    public ProjectDataMapping()
    {
        Bag(data => data.Branches,
            mapper =>
                {
                    mapper.Access(Accessor.ReadOnly);
                    mapper.Inverse(false);                       
                }, relation => relation.OneToMany());

    }
}

テーブル名と列名は規則に従って作成されます。親プロパティを設定して新しい BranchDate を作成して保存すると、親の Branches コレクションに表示されません。

不足している設定は何ですか?

コードによる双方向 NHibernate マッピングhttp://notherdev.blogspot.cz/2012/02/nhibernates-mapping-by-code-summary.htmlを読みましたが、まだ正しく設定できていません。

編集:この動作を検証するコード

        [Test]
    public void CanSaveAndLoadBranch()
    {
        var session = InMemoryDatabase.GetSession();

        var project = new ProjectData {Name = "ratata"};
        var branch = new BranchData {ProjectData = project};

        using (var tx = session.BeginTransaction())
        {
            session.Save(project);
            session.Save(branch);

            tx.Commit();
        }
        var branches = project.Branches;
        //branches are empty

        var freshProject = session.Query<ProjectData>().Where(x => x.Id == project.Id).First();
        var freshBranches = freshProject.Branches;
        //branches are  empty here, too

        var fetched = session.Query<ProjectData>().Where(x => x.Id == project.Id).FetchMany(x => x.Branches).First();
        var fetchedBranches = fetched.Branches;
        //branches are  empty here, too


        var queriedOn = session.Query<ProjectData>().Where(x => x.Branches.Any()).ToList();
        //this does return the project, but Branches property is still empty


    }
4

1 に答える 1

1

メモリ内のデータを操作する場合、関係の両側を管理する責任があります。Addのメソッドを使用すると、これを簡単に行うことができますProjectData

public virtual void Add(BranchData branch)
{
    branch.ProjectData = this;
    Branches.Add(branch);
}

一方、NHibernate は、オブジェクトを適切に水和および脱水する役割を果たします。ただし、クエリはすべて同じセッション内で発生しているため、これは表示されません。次のコードを検討してください。

var project = new ProjectData();
session.Save(project);
session.Flush();
var freshProject = session.Get<ProjectData>(project.Id);
if (ReferenceEquals(project, freshProject))
    Console.WriteLine("They're the same instance.");

このコードは、「それらは同じインスタンスです」と表示します。そのインスタンスには、正しいかどうかに関係なく、初期化したとおりに関係が設定されたままになります。

逆側の関係を設定することを怠った場合project.Branches、NHibernate は問題なく保存できますが、そのセッションの間は一貫性がないように見えます。セッションを閉じて新しいセッションを開く (これはインメモリ テストでは問題になる可能性があります) か、単に or を呼び出すとsession.Clear()、再度ロードしたときにsession.Evict(project)データが表示されます。project.Branches

于 2013-09-04T18:16:00.063 に答える