EF在计算列表时避免提取

时间:2015-08-10 12:29:40

标签: entity-framework

我有一个场景,我试图计算列表中的项目。此列表是来自EF的代理。但是,当我调用Count方法时,将获取列表中的每个项目,并且它会降低很多性能。有没有办法避免它? 寻找一个例子:

域类:

public class Desire
{
    public virtual int Id { get; set; }
    public virtual string Title { get; set; }
    public virtual List<Vote> Votes { get; set; }
}

public class Vote
{
    public virtual int Id { get; set; }
    public virtual UserProfile User { get; set; }
    public virtual DateTime DateTime { get; set; }
}

存储库:

    public IQueryable<Desire> GetQuery()
    {
        return db.Desires;
    }

域名服务:

    public IQueryable<Desire> GetDesires()
    {
        return repository.GetQuery();
    }

ASP MVC查看:

<!-- here Votes is a proxy from EF -->
<!-- When Count is called, the items are fetched decreasing the performance -->    
<h2>Total Votes: @item.Votes.Count</h2> 

2 个答案:

答案 0 :(得分:1)

始终尝试使用View Model而不是EF的实体。使用视图模型填充所需数据,并将视图模型传递给view而不是model。

public class DesireViewModel
{
    public int Id { get; set; }
    public string Title { get; set; }
    public int VotesCount{ get; set; }
    // add votes themselves if you really need them
    // public IEnumerable<VoteViewModel> Votes { get; set; }
}

在您的操作方法中填写DesireViewModel而不是Desire

public ActionResult MyAction()
{
    var model=_db.Desires.Select(d=>
        new DesireViewModel
        {
            Id=d.Id,
            Title=d.Title,
            VotesCount=d.Votes.Count(),
        });
    return View(model);
}

您的视图模型现在是IEnumerable<DesireViewModel>而不是IEnumerable<Desire>

@model IEnumerable<.Your.Namespace.DesireViewModel>

// inside loop
<h2>Total Votes: @item.VotesCount</h2>

答案 1 :(得分:0)

因为您使用Count funktion查询item.Votes,EF必须获取所有项目(Count()强制执行Query之前)。 据我所知,唯一不获取所有数据(带物化)的方法是使用原始sql语句:

item.Database.SqlQuery<int>("SELECT Count(*) FROM Vote;");