2

我有 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();

谢谢!

4

3 回答 3

1

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

 var cliente = context.Clientes
       .Include(e => e.Enderecos)
       .Include(e1 => e1.Enderecos.Select(cep => cep.CEP.Cidade.UF))
       .SingleOrDefault();
于 2013-10-30T01:30:35.477 回答
0

“ObjectContext 实例已被释放,不能再用于需要连接的操作。”

你得到这个是因为在你IEnumerable.GetEnumerator()被调用DbQuery之后DbContext.Dispose被调用。

发生这种情况的典型原因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());
        }
    }
}

此方法可确保我们IEnumerable.GetEnumerator()DbContext仍处于活动状态时运行。但是我更喜欢下一种方法......

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 对象的生存时间仅足以被视图写入,从而减少了内存负载。

于 2013-10-30T04:04:09.443 回答
0

答案就在问题本身

How can I Include Multiples Tables??

只有我们, ScartagINCLUDE已经解释了很多答案

于 2013-10-30T04:08:16.837 回答