作者热门文章
- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
背景
我将项目中的LINQ-to-SQL代码更改为Entity Framework。大部分更改都相对简单,但是,我遇到了一个相当大的问题。使用LINQ-to-SQL,我能够使用如下存储过程来加载整个对象图(针对模型B):
ViewModel.Model = MyDbContext.usp_ModelA_GetByID(AId).Single();
List<ModelB> Details =
(from b in MyDbContext.usp_ModelB_GetByID(BId)
join c in MyDbContext.usp_ModelC_GetAll()
on b.CId equals c.CId
select new ModelB()
{
BId = b.BId,
CId = b.CId,
C = c
}).ToList();
ViewModel.Model.ModelBs.AddRange(Details);
ViewModel.Model = MyDbContext.usp_ModelA_GetByID(AId).Single();
List<ModelB> Details =
(from b in MyDbContext.usp_ModelB_GetByID(BId)
join c in MyDbContext.usp_ModelC_GetAll()
on b.CId equals c.CId
select new ModelB()
{
BId = b.BId,
CId = c.CId,
C = c
}).ToList();
ViewModel.Model.ModelBs = new EntityCollection<ModelB>();
foreach (ModelB detail in Details)
{
ViewModel.Model.ModelBs.Attach(detail);
}
ViewModel.Model =
(from a in MyDbContext.usp_ModelA_GetByID(AId)
select new A()
{
AId = a.AId,
ModelBs = (from b in MyDbContext.usp_ModelB_GetByID(BId)
join c in MyDbContext.usp_ModelC_GetAll()
on b.CId equals c.CId
select new ModelB()
{
BId = b.BId,
CId = b.CId,
C = c
}).ToEntityCollection()
}).Single();
public static EntityCollection<TEntity> ToEntityCollection<TEntity>(
this IEnumerable<TEntity> source) where TEntity : class, IEntityWithRelationships
{
EntityCollection<TEntity> set = new EntityCollection<TEntity>();
foreach (TEntity entity in source)
{
set.Attach(entity);
}
return set;
}
(from b in MyDbContext.usp_ModelB_GetByID(BId)
join c in MyDbContext.usp_ModelC_GetAll()
on b.CId equals c.CId
select new ModelB()
{
BId = b.BId,
CId = b.CId,
C = c //<------Setting a navigation property and EF figures out that it belongs
}).ToList();
(from a in MyDbContext.usp_ModelA_GetByID(AId)
select new ModelA()
{
AId = a.AId,
ModelBs = MyDbContext.usp_ModelB_GetByID(BId).ToEntityCollection() //<----Won't let me set the navigation property when the navigation property is a collection.
}).Single();
最佳答案
可以用相当简单的方式完成此操作,但需要一些人工。 Here is an MSDN post处理具有多个结果集的存储过程,该过程同时显示了代码优先和数据库优先的方法。
例子:
加载EntityB过程:
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
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
[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<EntityA> EntityAsViaPrimary { get; set; }
[InverseProperty( "AlternativeEntityB" )]
public virtual ICollection<EntityA> EntityAsViaAlternative { get; set; }
}
EntityA
)
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<EntityA>( reader, "EntityAs", MergeOption.AppendOnly );
reader.NextResult();
var bEntities = objContext
.Translate<EntityB>( reader, "EntityBs", MergeOption.AppendOnly );
}
finally
{
db.Database.Connection.Close();
}
}
}
EagerLoadEntityA( 1234 );
var entityA = db.EntityAs.Find( 1234 ); // cached
var primB = entityA.PrimaryEntityB; // this is already loaded
关于c# - Entity Framework -使用存储过程急于加载对象图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21538728/
我是一名优秀的程序员,十分优秀!