2015-04-01 28 views
0

我有NHibernate的两个实体之间的一对多的关系:如何启用关系的延迟加载INSERT后NHibernate的

public class Application 
{ 
    public string TaskId { get; set; } // Foreign key reference 
    public Task Task { get; set; }  // The relation/navigation property 
} 

db.Web.Applications.Create方法只是调用NHibernate会话的“SaveOrUpdate”法内交易。

的初步认识映射:

internal class ApplicationMap : ClassMap<Application> 
{ 
    public ApplicationMap() : base() 
    { 
     Schema(...); 
     Table(...); 

     CompositeId() 
      .KeyProperty(app => app.UserId, "...") 
      .KeyProperty(app => app.TaskId, "task_id") 
      .KeyProperty(app => app.TransactionId, "..."); 

     // Relations 

     References(app => app.Task, "task_id") 
      .ForeignKey("taskid") 
      .Unique() 
      .Not.Insert() 
      .Cascade.Persist(); 
    } 
} 

internal class TaskMap : ClassMap<Task> 
{ 
    public TaskMap() 
    { 
     Schema(..); 
     Table(...); 

     Id(task => task.Id, "task_id"); 

     HasMany(task => task.Applications) 
      .KeyColumn("task_id"); 
    } 
} 

当我写了一个测试对一个真正的数据库中创建一个新的Application我发现导航属性不是插入后延迟加载:

var app = new Application(...) 
{ 
    TaskId = "..." 
}; 

db.Web.Applications.Create(app); 
db.SaveChanges(); 

var actual = db.Web.Applications.Find(app.UserId, app.TaskId, app.TransactionId); 

// actual.Task is null 

的映射按我期望的方式工作,但在插入新的Application对象后,访问Task属性返回null,而不是从数据库延迟加载该实体。这可以做到,如果是这样,怎么做?

回答

1

我认为你的问题出现在你已经映射Application类的方式以及它对应的Task对象关系中。我想你应该像这样映射它:

​​

没有必要为外键关系映射特定的id属性。我总是只映射实体。这种方式更容易。那么你上面的代码插入将是这样的:

var app = new Application(...) 
{ 
    Task = session.Load<Task>(taskId) 
}; 

db.Web.Applications.Create(app); 
db.SaveChanges(); 

var actual = db.Web.Applications.Find(app.UserId, app.TaskId, app.TransactionId); 
+0

问题是我需要的任务编号无处不在。我会尝试使用这种映射技术,也许为TaskId创建一个自定义getter属性,而不必一直输入'app.Task.Id'。 – 2015-04-01 16:29:56

+0

@GregBurghardt“app.Task.Id”vs“app.TaskId”真的有什么不同吗?我们通过这样的关系在我们的代码中处处做到这一点。也是这样,你不必对同一件事物进行双重映射。 – 2015-04-01 17:04:21

+0

我明白我现在做错了什么。起初我没有去寻找这个解决方案,因为通常我会直接调用方法或属性而不是对象的属性,因为这会创建更容易重构的代码。我以为只是包括一个'公共字符串TaskId {得到{返回Task.Id; }}'Application'类中的委托属性将映射关闭,但我在'QueryOver'调用中使用了'TaskId'委托属性。 _这是搞砸了NHibernate。我需要'session.QueryOver ().Where(app => app.Task.Id ==“...”)''。 – 2015-04-02 12:50:53