2013-09-02 3 views
0

У меня есть отношение родительских детей и в настоящее время существует только ссылка от каждого дочернего элемента к родительскому (есть столбец внешнего ключа в дочерней таблице). Я хотел бы добавить родительское свойство readnly 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 с набором родительских свойств, он не отображается в коллекции ветвей родителя.

Какую настройку мне не хватает?

Я прочитал Bi-directional NHibernate mapping by code и http://notherdev.blogspot.cz/2012/02/nhibernates-mapping-by-code-summary.html, и я все еще не могу установить его должным образом.

Edit: Код, который проверяет это поведение

 [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 


    } 
+0

Вы пытаетесь перечислить коллекцию ветвей в том же ISession, который использовался для создания сохранения свойства Branch with Project? Если вы делаете это, попробуйте использовать другое ISession. Возможно, команда сохранения регистра в базе данных еще не была очищена. – cidico

+0

Можете ли вы показать код, который вы используете для этого: «создайте и сохраните новый BranchDate с набором родительских свойств», а также код, который проверяет это: «он не отображается в коллекции« Ветки »родителя». –

+0

Я добавлю его на вопрос –

ответ

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() или session.Evict(project), тогда вы увидите данные в project.Branches при повторной загрузке.

+0

Спасибо, я попробую очистить сеанс. В приложении это не будет проблемой, поскольку запросы и вставки выполняются в разных сеансах в любом случае. –