实体框架中的循环引用和开放式datareader

时间:2017-12-30 16:50:11

标签: c# json asp.net-mvc entity-framework parent-child

我如何在MVC中解决这个问题

我有以下数据模型

public class Game
{
    public int GameID { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Player> Players { get; set; 
}

public class Player
{
    public int PlayerID { get; set; }

    public string Name { get; set; }

    public int GameID { get; set; }
    public virtual Game Game { get; set; }
}

在Context类中,我正在创建两个数据集

    public DbSet<Game> Games { get; set; }
    public DbSet<Player> Players { get; set; }

我现在有一个简单的MVC控制器,通过Get API应该返回一个带有游戏列表的json数据集,每个游戏列出一个玩家列表......

我尝试了MVC控制器的这种实现

    public JsonResult Games()
    {
        var Games = db.Games;
        return Json(Games, JsonRequestBehavior.AllowGet);
    }

有了这个,我得到一个错误,告诉我已经有一个开放的datareader。 我有点理解,但我没有解决它的知识。

为了解决这个问题,我试图把它放到List&lt;&gt;

    public JsonResult Games()
    {
        var Games = db.Games.ToList();
        return Json(Games, JsonRequestBehavior.AllowGet);
    }

此时我收到循环引用错误。 (我猜它是来自每个玩家的虚拟游戏。但如果我需要它呢?

这个问题的正确和简单方法是什么?

我认为它必须是一个基本的东西,因为它是一个基本的父/子配置。但我错过了一些东西。

2 个答案:

答案 0 :(得分:1)

当我们严重设计实体时,通常会出现循环引用错误。这就像我们一样

public class Bank
{
    public int Id;
    public string Name;
}

public class BankBranch
{
   public int Id;
   public string BranchName;
   public int BankId { get; set; }
   [ForeignKey("BankId")]
   public virtual Bank Bank { get; set; }
}

当我们创建公司实体并尝试在此公司实体中添加BankBankBranch IDs时,VS会因为多个跳转点而添加或更新迁移时出错Bank实体。如果我们有如下设计

public class Company
{
   public int Id;
   public int BankBranchId { get; set; }
   [ForeignKey("BankBranchId")]
   public virtual BankBranch BankBranch { get; set; }
}

我们可以从分支机构到公司和银行的分支机构,如下所示: company.BankBranch.Bank

即使我们具有结构良好的设计,EF也会出现此错误。我只是使用ProxyCreationEnable属性从控制器中检索Json数据。

public JsonResult GetAllBankList()
{
   db.Configuration.ProxyCreationEnabled = false;
   var bankList = db.Banks.ToList();
   return Json(bankList, JsonRequestBehavior.AllowGet);
}

答案 1 :(得分:0)

您可以关闭代理以避免循环引用。

YourDbContext.Configuration.ProxyCreationEnabled = false;
YourDbContext.Configuration.ProxyCreationEnabledLazyLoadingEnabled = false;