如何在 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();

谢谢!

如何在 linq 中包含多个表,以便使用 mvc4 C# 快速加载实体

您可以简单地包含整个导航路径。

 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解释了很多