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

时间:2013-06-04 10:38:36

标签: entity-framework-4.1

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

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

eventdiscount

每个event可以有多个discount s。

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

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

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

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>
   }

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

1 个答案:

答案 0 :(得分: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表的子集。

相关问题