Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework CTP5 - Reading Multiple Record Sets From a Stored Procedure

In EF4, this was not easily possible. You either had to degrade to classic ADO.NET (DataReader), use ObjectContext.Translate or use the EFExtensions project.

Has this been implemented off the shelf in EF CTP5?

If not, what is the recommended way of doing this?

Do we have to cast the DbContext<T> as an IObjectContextAdapter and access the underlying ObjectContext in order to get to this method?

Can someone point me to a good article on doing this with EF CTP5?

like image 474
RPM1984 Avatar asked Mar 09 '11 22:03

RPM1984


1 Answers

So i got this working, here's what i have:

internal SomeInternalPOCOWrapper FindXXX(string xxx)
{
    Condition.Requires(xxx).IsNotNullOrEmpty();

    var someInternalPokey = new SomeInternalPOCOWrapper();
    var ctx = (this as IObjectContextAdapter).ObjectContext;

    var con = new SqlConnection("xxxxx");
    {
        con.Open();
        DbCommand cmd = con.CreateCommand();
        cmd.CommandText = "exec dbo.usp_XXX @xxxx";
        cmd.Parameters.Add(new SqlParameter("xxxx", xxx));

        using (var rdr = cmd.ExecuteReader())
        {
            // -- RESULT SET #1
            someInternalPokey.Prop1 = ctx.Translate<InternalPoco1>(rdr);

            // -- RESULT SET #2
            rdr.NextResult();
            someInternalPokey.Prop2 = ctx.Translate<InternalPoco2>(rdr);

            // -- RESULT SET #3
            rdr.NextResult();
            someInternalPokey.Prop3 = ctx.Translate<InternalPoco3>(rdr);

            // RESULT SET #4
            rdr.NextResult();
            someInternalPokey.Prop4 = ctx.Translate<InternalPoco4>(rdr);
        }
        con.Close();
    }

    return someInternalPokey;
}

Essentially, it's basically like classic ADO.NET. You read the DbReader, advance to the next result set, etc.

But at least we have the Translate method which seemingly does a left-to-right between the result set fields and the supplied entity.

Note the method is internal.

My Repository calls this method, then hydrates the DTO into my domain objects.

I'm not 100% happy with it for 3 reasons:

  1. We have to cast the DbContext as IObjectContextAdapter. The method Translate should be on DbContext<T> class IMO.
  2. We have to use classic ADO.NET Objects. Why? Stored Procedures are a must have for any ORM. My main gripe with EF is the lack of the stored procedure support and this seems to not have been rectified with EF CTP5.
  3. You have to open a new SqlConnection. Why can't it use the same connection as the one opened by the EF Context?

Hope this both helps someone and sends out a message to the EF team. We need multiple result support for SPROCS off the shelf. You can map a stored proc to a complex type, so why can't we map a stored proc to multiple complex types?

like image 114
RPM1984 Avatar answered Nov 09 '22 03:11

RPM1984