2010-12-15 137 views
1

我是实体框架的新手。我使用Ninject在MVC中创建了一个多层应用程序。
我在数据库中有三个表。说表A,表B和表C.实体框架实体没有显示相关实体的属性

Table A has a foreign key relating it to Table B 
Table B has a foreign key relating it to Table C 

Table A => Table B => Table C 

我的应用程序有一个“服务”,将从MVC控制器调用。
该服务充当每个实体(即TableAService,TableBService)的存储库,该实体负责从EF DataContext创建,读取,更新或删除实体,并且可能对这些实体执行业务逻辑。

在我的MVC控制器中,我提到了相应的服务。例如:

private TableAService _tableAService; 

public TableAController(EFDataContext dataContext) 
{ 
    _tableAService = new TableAService(dataContext); 
} 

public ActionResult Index() 
{ 
    return View(); 
} 

TableAService会是这个样子:

private EFDataContext _dataContext; 

public TableAService(EFDataContext dataContext) 
{ 
    _dataContext = dataContext; 
} 

public TableA GetById(int tableAId) 
{ 
    _dataContext.TableA.SingleOrDefault(ta => ta.TableAId == tableAId); 
} 

我明白,在这个例子的服务将被紧密地结合到数据源,我的实际执行情况略有不同,但概念是相同的,我有一个dataContext服务,我想从中返回实体。

问题: - 当我在TableAService的GetById方法中时,SingleOrDefault给了我一个TableB导航属性,它允许我访问所有TableB的属性,包括TableC导航属性。

但是,当我将TableA传递回控制器时,我无法访问TableB的任何属性。

中的服务我也试过:

private ObjectSet<TableA> _objSet = _dataContext.CreateObjectSet<TableA>(); 

return _objSet.SingleOrDefault(ta => ta.TableAId == tableAId); 

这似乎并没有做出能够对表B从访问表C导航属性有什么区别表A实体。

任何帮助将不胜感激!

干杯,

詹姆斯

回答

0

这需要一些挖掘,但我遇到的问题是我的应用程序没有引用System.Data.Entity。

向应用程序添加引用允许我从控制器内访问相关对象的属性。

感谢您的答案,他们确实帮助我排除了可能性。我每个人都投了票。

2

试着改变你的GetById方法:

public TableA GetById(int tableAId) 
{ 
    return _dataContext.TableA.Include("TableB").SingleOrDefault(ta => ta.TableAId == tableAId); 
} 

如果你想要得到的表C记录为好,用途:

public TableA GetById(int tableAId) 
{ 
    return _dataContext.TableA.Include("TableB.TableC").SingleOrDefault(ta => ta.TableAId == tableAId); 
} 

的原因是Entity Framework使用“延迟加载”,这意味着这些东西直到你真的需要它才从数据库加载。麻烦的是,一旦您退出服务,数据上下文不再存在以获取表B的记录。方法Include指示EF立即加载来自相关表的数据。

3

导航属性的内容只能在活动ObjectContext的范围内加载。

这是必需的,因为实际的行将通过往返数据库获取。
在你的情况下,你试图访问一个导航属性,ObjectContext用于检索实体的第一个地方已经被丢弃,连接丢失。

假设你正在使用Entity Framework 4有2个解决问题的对策:

  • 预先加载:相关实体被加载了前面,那是你明确地指示实体框架加载所有相关实体,而它正在检索查询的结果。
    这可以通过几种不同的方式完成:通过在导航属性中调用ObjectQuery.Include方法或调用Load方法,或者在ObjectContext.LoadProperty方法中将相关实体包括在查询的投影中。
  • 延迟加载:相关实体是按需加载的,也就是当导航属性的getter被第一次访问时。请注意,这仍然必须在ObjectContext的范围内完成。

在使用Include方法的情况下,预先加载可能是最合适的解决方案:

public TableA GetById(int tableAId) 
{ 
    return _dataContext.TableA 
     .Include("TableB.TableC") // use dot-notation to specify depth in the object graph 
     .SingleOrDefault(ta => ta.TableAId == tableAId); 
} 

相关资源: