0

具有一对多导航的实体框架4.1如何防止相关实体的循环加载?

例如:两个表具有一对多关系

eventdiscount

每个event可以有多个discounts。

当我创建折扣实体对象时,我会通过延迟加载获得事件对象。使用事件对象,我可以收集相关折扣并继续循环。

我相信如果这种加载的数据很大,性能会降低。

如何在实体框架中处理这种情况。

public Event()
{
  public virtual ICollection<discount> discounts{ get; set; }    
}

public Discount
{    
  public virtual Event Event {get;set;}    
}

另一个前任:

 [Bind(Exclude = "AlbumId")]
public class Album
  {
    [ScaffoldColumn(false)]
    public int AlbumId { get; set; }

    [DisplayName("Genre")]
    public int GenreId { get; set; }

    public virtual Genre Genre { get; set; }        

  }


   public partial class Genre
  {
    public int GenreId { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public List<Album> Albums { get; set; }
  }


 public ViewResult Index()
        {
            var albums = db.Albums.Include(a => a.Genre).Include(a => a.Artist);
            return View(albums.ToList());
        }



   @foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Genre.Name)
        </td>
        <td>
            @Truncate(item.Artist.Name, 25)
        </td>
        <td>
            @Truncate(item.Title, 25)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Price)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.AlbumId }) |
            @Html.ActionLink("Details", "Details", new { id=item.AlbumId }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.AlbumId })
        </td>
    </tr>
   }

在上面的例子中。专辑已包含流派。所以专辑有流派,然后流派有专辑列表,它会继续。它会增加 dbcontext 的大小还是会降低性能。这是处理加载相关导航属性的错误方法吗?

4

1 回答 1

0

假设我们首先使用实体​​框架代码。您将有两个 POCO 课程;将映射到同名表的事件和折扣。

public class Event
{
    public Event()
    {
        this.Discounts = new HashSet<Discount>();
    }

    public int Id { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Discount> Discounts { get; set; }
}

public class Discount
{
    public int Id { get; set; }
    public decimal Amount { get; set; }

    public int EventId { get; set; }
    public virtual Event Event { get; set; }

}

然后你会有一个继承自 DBContext 的类

public class ExampleContext: DbContext
{
    public DbSet<Event> Events { get; set; }
    public DbSet<Discount> Discount { get: set; }
}

为了通过 EventId = 1 的事件获得折扣

var db = new ExampleContext();

var discounts = db.Discounts.Where(d => d.EventId == 1);

如果您有一个事件对象,您可以按事件访问折扣,如下所示

var event = db.Events.FirstOrDefault(e => e.Id == 1);

var discount = db.Entry(discount).Reference(d => d.Event).Load();

如果您采用类似的方法,我认为您不会对实体的循环加载有任何问题。我希望这有帮助!

编辑:您使用流派和专辑的代码优先方法似乎是正确的。假设您正确设置了 POCO 类和 DbContext 类,那么性能将取决于您编写 LINQ 查询的方式。好的 LINQ 查询会生成好的 SQL 代码。错误的 LINQ 查询会生成错误的 SQL 代码。LINQPad

http://www.linqpad.net

是一个很棒的免费工具,用于编写 linq 查询并检查它们生成的 SQL 代码和查询结果。例如

var albums = db.Albums;

产生相当于

SELECT * FROM Albums;

您应该很少返回实体或表中的所有记录。另一方面

var albums = db.Albums.Where(a => a.GenreId == 1).ToList();

会产生类似的东西

SELECT * FROM Albums
WHERE GenreId = 1;

它只返回 Albums 表的一个子集。

于 2013-06-04T13:42:15.617 回答