Background
I am changing my LINQ-to-SQL code in my project to Entity Framework. Most of the change over was relatively simple, however, I have run into
It can be done in a fairly simple way but takes some manual effort. Here is an MSDN post on handling stored procedures with multiple result sets which shows both a code first and database first approach.
Example:
Load EntityB proc:
create proc dbo.Get_EntityB_by_EntityAId( @aId int )
as
select distinct
b.EntityBId
, b.Description
from
EntityA a
left outer join EntityB b
on a.PrimaryEntityB_EntityBId = b.EntityBId
left outer join EntityB b2
on a.AlternativeEntityB_EntityBId = b2.EntityBId
where
a.EntityAId = @aId
go
Load EntityA proc (which calls load B proc)
create proc dbo.Get_EntityA_by_Id( @id int )
as
-- use a select statement
select
a.EntityAId
, a.Description
, a.PrimaryEntityB_EntityBId
, a.AlternativeEntityB_EntityBId
from
EntityA a
where
a.EntityAId = @id
-- and/or other sprocs
exec dbo.Get_EntityB_by_EntityAId @id
go
Entity classes
[Table("EntityA")]
public partial class EntityA
{
public int EntityAId { get; set; }
public string Description { get; set; }
public virtual EntityB PrimaryEntityB { get; set; }
public virtual EntityB AlternativeEntityB { get; set; }
}
[Table("EntityB")]
public partial class EntityB
{
public int EntityBId { get; set; }
public string Description { get; set; }
[InverseProperty("PrimaryEntityB")]
public virtual ICollection EntityAsViaPrimary { get; set; }
[InverseProperty( "AlternativeEntityB" )]
public virtual ICollection EntityAsViaAlternative { get; set; }
}
Method that calls sproc and handles results (for this method, you could return the one EntityA
if you'd like)
public static void EagerLoadEntityA( int aId )
{
using( var db = new TestEntities() )
{
// if using code first
db.Database.Initialize( false );
var cmd = db.Database.Connection.CreateCommand();
cmd.CommandText = "dbo.Get_EntityA_by_Id";
db.Database.Connection.Open();
try
{
var reader = cmd.ExecuteReader();
var objContext = ( ( IObjectContextAdapter )db ).ObjectContext;
var aEntities = objContext
.Translate( reader, "EntityAs", MergeOption.AppendOnly );
reader.NextResult();
var bEntities = objContext
.Translate( reader, "EntityBs", MergeOption.AppendOnly );
}
finally
{
db.Database.Connection.Close();
}
}
}
Usage:
EagerLoadEntityA( 1234 );
var entityA = db.EntityAs.Find( 1234 ); // cached
var primB = entityA.PrimaryEntityB; // this is already loaded