将存储过程中的额外列映射到Entity Framework代码的第一个模型

时间:2015-07-13 12:33:49

标签: linq entity-framework stored-procedures ef-code-first repository-pattern

我首先使用实体​​框架代码,使用ASP.NET MVC的通用存储库模式。我有两个表CategoryProduct

我的product模型类就像这样

  Public class Product
  {
     public int ProductID{get;set;}

     Public int CategoryID{get;set;}

     [ForeignKey("CategoryID")]
     public virtual Category Category{get;set;}

     [NotMapped]
     public string CategoryName{get;set;}
  }

只要我使用DBContext获取数据,模型就能正确绑定。

但是当我从映射到Product对象的存储过程获取产品列表时,我遇到了问题。所以它没有映射Category对象的Product属性,因此我无法获得Category.CategoryName

因此,我在产品类中添加了一个[NotMapped]属性为CategoryName的新属性。但它也不受存储过程的约束。

如果我删除[NotMapped]属性,那么它从存储过程中正确绑定,但在通过DbContext(Linq)获取产品时会再次出现错误。

请在这方面帮助我。

1 个答案:

答案 0 :(得分:0)

您不需要添加额外的属性,对返回实体类型的查询使用DbSet.SqlQuery方法。返回的对象必须是DbSet对象所期望的类型,并且它们将由数据库上下文自动跟踪,除非您关闭跟踪。

var products= _context.Products.SqlQuery("storedProcedureName",params);

SP返回的列应该与实体类型的属性匹配,否则会引发异常。

执行完SP后,您应该可以通过CategoryName导航属性获取Category

var catName=someProduct.Category.CategoryName;

另一方面,Database.SqlQuery返回的数据不会被数据库上下文跟踪,即使您使用此方法检索实体类型也是如此。如果要使用此方法跟踪执行SP后获得的实体,可以尝试以下操作:

//Attach the entity to the DbContext
_context.Product.Attach(someProduct);

//The Category navigation property will be lazy loaded
var catName=someProduct.Category.CategoryName;

如果您已禁用延迟加载,则可以明确加载导航属性:

//Load the Category navigation property explicitly
_context.Entry(someProduct).Reference(c => c.Category).Load();