Entity Framework 4.1, MVC3 JsonResult and Circular

2019-08-02 16:10发布

问题:

I'm trying to learn Entity Framework Code First development with ASP.NET MVC3.

Let's say I have a simple data Model for an Auction and Bids and I'd like to query all the Auctions and their Bids.

I have turned off LazyLoadingEnabled and ProxyCreationEnabled.

Here is the code I have:

public class MiCoreDb2Context : DbContext
{
    public MiCoreDb2Context()
        : base()
    {
        this.Configuration.LazyLoadingEnabled = false;
        this.Configuration.ProxyCreationEnabled = false;
    }

    public DbSet<Auction> Auctions { get; set; }
    public DbSet<Bid> Bids { get; set; }
}

public class Auction
{
    public int AuctionId { get; set; }
    public virtual ICollection<Bid> Bids { get; set; }
}

public class Bid
{
    public long BidId { get; set; }
    public int AuctionId { get; set; }

    [ForeignKeyAttribute("AuctionId")]
    public virtual Auction Auction { get; set; }
}


public JsonResult Thing()
{
    List<Auction> auctions;

    using (var db = new MiCoreDb2Context())
    {
        var auctions = (from a in db.Auctions.Include("Bids") select a).ToList();
    }

    return Json(auctions, JsonRequestBehavior.AllowGet);
}

When I load the page, a circular reference occurs. How will I get around this?

回答1:

When I load the page, a circular reference occurs. How will I get around this?

By using view models (and by the way that's the answer to any question you might have concerning ASP.NET MVC :-)). Ayende Rahien has an excellent series of blog posts on this topic.

Conclusion: absolutely always pass/take view models to/from a view. Absolutely never pass/take models (EF, domain, ...) to/from a view. Once this fundamental rule is being respected you will find out that everything works.



回答2:

I solved this problem by doing a projection in the Linq to Entities query. This will create anonymous types which can be serialized to json without any circular reference issues.

var result = 
from Item in dbContext.SomeEntityCollection
where SomePredicate
select new { Property1 = Item.Property1, Property2 = Item.Property2  };

Return Json(result, JsonRequestBehavior.AllowGet);

BOb