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 集合中。

我缺少什么设置?

我已经通过代码和http://notherdev.blogspot.cz/2012/02/nhibernates-mapping-by-code-summary.html阅读了双向 NHibernate 映射,但我仍然无法正确设置它。

编辑:验证此行为的代码

        [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 仍然可以很好地保存它,但它仍然会在该会话期间继续看起来不一致。如果您关闭会话并打开一个新会话(这可能对您的内存测试有问题),或者只是调用session.Clear()or session.Evict(project),那么您将在project.Branches再次加载时看到数据。

于 2013-09-04T18:16:00.063 回答