如何在 linq 中包含多个表,以便使用 mvc4 C# 快速加载实体
本文关键字:mvc4 实体 加载 linq 包含多 | 更新日期: 2023-09-27 18:37:27
我有 6 个类,我尝试使用实体linq
来获取最后一个更深表的SiglaUF
信息(在视图中 - MVC)。问题是我收到以下错误:
"ObjectContext 实例已被释放,不能再用于需要连接的操作。
视图是这样的:
> @model IEnumerable<DiskPizzaDelivery.Models.EnderecoCliente> > @foreach (var item in Model) { > @Html.DisplayFor(modelItem => item.CEP.Cidade.UF.SiglaUF) > }
我使用的查询:
var cliente = context.Clientes
.Include(e => e.Enderecos)
.Include(e1 => e1.Enderecos.Select(cep => cep.CEP))
.SingleOrDefault();
问题是:如何将此查询改进为预加载(预先加载)"Cidade"和"UF"?
请参阅下面的课程:
public partial class Cliente
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int IdCliente { get; set; }
public string Email { get; set; }
public string Senha { get; set; }
public virtual ICollection<EnderecoCliente> Enderecos { get; set; }
}
public partial class EnderecoCliente
{
public int IdEndereco { get; set; }
public int IdCliente { get; set; }
public string CEPEndereco { get; set; }
public string Numero { get; set; }
public string Complemento { get; set; }
public string PontoReferencia { get; set; }
public virtual Cliente Cliente { get; set; }
public virtual CEP CEP { get; set; }
}
public partial class CEP
{
public string CodCep { get; set; }
public string Tipo_Logradouro { get; set; }
public string Logradouro { get; set; }
public string Bairro { get; set; }
public int CodigoUF { get; set; }
public int CodigoCidade { get; set; }
public virtual Cidade Cidade { get; set; }
}
public partial class Cidade
{
public int CodigoCidade { get; set; }
public string NomeCidade { get; set; }
public int CodigoUF { get; set; }
public virtual ICollection<CEP> CEPs { get; set; }
public virtual UF UF { get; set; }
public virtual ICollection<UF> UFs { get; set; }
}
public partial class UF
{
public int CodigoUF { get; set; }
public string SiglaUF { get; set; }
public string NomeUF { get; set; }
public int CodigoCidadeCapital { get; set; }
public virtual ICollection<Cidade> Cidades { get; set; }
public virtual Cidade Cidade { get; set; }
}
var cliente = context.Clientes
.Where(c => c.Email == email)
.Where(c => c.Senha == senha)
.Include(e => e.Enderecos)
.Include(e1 => e1.Enderecos.Select(cep => cep.CEP))
.SingleOrDefault();
谢谢!
您可以简单地包含整个导航路径。
var cliente = context.Clientes
.Include(e => e.Enderecos)
.Include(e1 => e1.Enderecos.Select(cep => cep.CEP.Cidade.UF))
.SingleOrDefault();
"ObjectContext 实例已被释放,不能再用于需要连接的操作。
您之所以得到这个,是因为在您的DbContext.Dispose
被调用后,IEnumerable.GetEnumerator()
DbQuery
被调用。
ASP.Net MVC
中发生这种情况的典型原因是以下代码。
public class FooController : Controller
{
public ActionResult Index()
{
using(var database = new DatabaseContext())
{
var query = from x in database.Foos
...blah blah blah...
select x;
return View(query);
}
}
}
这是字幕。但是当视图运行时@foreach(var item in Model)
(隐式调用IEnumerable.GetEnumerator()
您的Controller.Index()
方法已经返回,因此您的数据库上下文已被释放。
有两种方法可以解决此问题。
public class FooController : Controller
{
public ActionResult Index()
{
using(var database = new DatabaseContext())
{
var query = from x in database.Foos
...blah blah blah...
select x;
return View(query.ToList());
}
}
}
此方法可确保我们在DbContext
仍处于活动状态时运行IEnumerable.GetEnumerator()
。但是我更喜欢下一种方法...
public class FooController : Controller
{
private DatabaseContext _database = new DatabaseContext();
public ActionResult Index()
{
var query = from x in database.Foos
...blah blah blah...
select x;
return View(query);
}
public override Dispose()
{
_database.Dispose();
}
}
原因是您可以向查询添加.AsStreaming()
和.AsNoTracking()
。这意味着您的 POCO 对象的生存时间仅足以由视图写入,从而减少了内存负载。
答案就在问题本身
How can I Include Multiples Tables??
只是我们INCLUDE
,答案已经被Scartag解释了很多