在Code First 4.1中执行存储过程

时间:2011-04-25 09:13:05

标签: entity-framework stored-procedures ef-code-first entity-framework-4.1

我理解存储过程映射不支持我的理解是我应该能够调用存储过程。

我有很多复杂的存储过程,而设计师我可以创建一个复杂的类型,我一切都很好。

现在在代码中首先让我假设我有以下存储过程,只是把一些愚蠢的东西放在一起给出一个想法。我想找一个有1个地址的学生。

在代码中我有一个学生和地址实体。但没有StudentAddressEntity,因为它是一个链接表。

我尝试过以下操作,但收到错误

  

“。”}附近的语法不正确   System.Data.Common.DbException {System.Data.SqlClient.SqlException}

ALTER Procedure [dbo].[GetStudentById]
   @StudentID int
AS
   SELECT  *
   FROM Student S
   left join StudentAddress SA on S.Studentid = sa.studentid
   left join Address A on SA.AddressID = A.AddressID
   where S.StudentID = @StudentID

C#代码:

using (var ctx = new SchoolContext())
{
   var student = ctx.Database.SqlQuery<Student>("GetStudentById,@StudentID",
                                                new SqlParameter("StudentID", id));
}

那里有任何例子如何调用sp并首先在代码中填充complexType,使用参数等。我可以挂钩到ADO.NET吗?

尝试只返回没有参数的所有学生的SP我收到此错误

  

System.SystemException =无法为属性创建值   'StudentAddress'的类型   'CodeFirstPrototype.Dal.Address'。只要   具有基本类型的属性是   支撑。

是因为我在某种程度上忽略了链接表吗?

有什么建议吗?

2 个答案:

答案 0 :(得分:7)

我相信您的例外实际上是:

  

','附近的语法不正确。

因为这是无效的声明:"GetStudentById,@StudentID"。它应该没有逗号:"GetStudentById @StudentID"

EF中存储过程的问题是它们不支持加载导航属性。 EF将仅实现主实体,并且不会加载导航属性。这可以通过例如EFExtensions来解决。 EFExtensions用于ObjectContext API,因此您必须检查它是否也可用于DbContext API。

答案 1 :(得分:0)

使用EFExtentions,它看起来像

using (var context = new SchoolContext())
{
    var command = context.CreateStoreCommand("GetStudentById", CommandType.StoredProcedure,
      new SqlParameter("StudentID", id));

    using (command.Connection.CreateConnectionScope())
    using (var reader = command.ExecuteReader())
    {
        // use the reader to read the data
        // my recommendation is to create a Materializer using EFExtensions see 
        // http://blogs.msdn.com/b/meek/archive/2008/03/26/ado-entity-framework-stored-procedure-customization.aspx

        // ex
        var student = Student.Materializer.Materialize(reader).SingleOrDefault();

        return student;
   }
}