2017-06-18 203 views
0

我有一个Items表和ItemVotes表,每个用户可以放弃投票或向下投票到一个项目和他/她的投票决定由ItemVotes表中的bool财产。现在我想要有一个Items排行榜的清单,为此,我们需要得到true票数减去false票数。LINQ查询计算投票计数

_ItemsService.GetAll(x => x.ItemVotes //here I have to order by vote) 

UPDATE:

项目实体:

public class Items : Entity<int> 
{ 
    public int UserId { get; set; } 
    public DateTime Date { get; set; } 
    public string Subject { get; set; } 

    public virtual ICollection<ItemVotes> ItemVotes { get; set; } 
} 

ItemVotes实体:

public class ItemVotes : Entity<int> 
{ 
    public int ItemId { get; set; } 
    public int UserId { get; set; } 
    public DateTime Date { get; set; } 
    public bool TypeVote { get; set; } 

    public virtual Items Items { get; set; } 
    public virtual Users Users { get; set; } 
} 

更新2:

我用吉拉德格林的答案在动作是这样的:

public ActionResult TopItems() 
    { 
     var items = _ItemsService.GetAllQuerable(x => x) 
      .OrderBy(item => item.ItemsVote.Sum(vote => vote.TypeVote ? 1 : -1)); 
     return View(items); 
    } 

enter image description here

这里是GetAllQuerable()功能:

public IEnumerable<T> GetAllQuerable(
     Expression<Func<T, 
     bool>> filter = null, 
     Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null, 
     string includeProperties = "") 
    { 
     return _repository.GetAllQuerable(filter, orderBy, includeProperties); 
    } 
+0

这将有助于展示更广泛的代码范围和你的对象 –

+0

@GiladGreen我已经更新了它。 – mohammad

+0

看到我的回答在 –

回答

1

为了实现我想有通过投票首先检索所有内容,然后通过所描述的逻辑命令他们的项目顺序列表:

retrievedItems.OrderBy(item => item.ItemVotes.Sum(vote => vote.TypeVote ? 1 : -1)); 

在当前的代码_ItemsService.GetAll(x => x.ItemVotes)...你输了知道哪个投票属于哪个项目,因此将一起获得所有项目的单个摘要的范围

+0

like @ michael_coxon的回答我已经得到了你的解决方案的两个错误。 – mohammad

+0

@mohammad请显示您使用代码的上下文。 –

+0

我希望我理解正确。我使用工作单元,例如'http:// techbrij.com/generic-repository-unit-of-work-entity-framework-unit-testing-asp-net-mvc' – mohammad

1

所有你需要做的是总和映射票true值到1false值到-1

_ItemsService.GetAll(x => x.ItemVotes) 
    .Sum(v => v.Vote ? 1 : -1) 
+0

以下我得到了两个错误:不能隐式地将类型'int'转换为'bool'并且不能将lambda表达式转换为块中预期的委托类型不隐式转换为委托返回类型 – mohammad

+0

这不回答这个问题.... –

0

让我们假设你有一个变量foo你有项目,那么:

bar = foo.OrderBy(item => item.ItemVotes.Sum(vote => vote.TypeVote ? 1 : -1)); 
0

您需要执行以下操作,以便根据他们的投票和最积极的投票项目先得到排序的项目清单。

在您的_ItemsService中公开一个方法GetOrderedItems,它将执行所有逻辑并返回您所需的结果,而不是在调用者内部将此逻辑运行到此服务。

GetOrderedItems(Func<bool,int> predicate) 
{ 
return items.OrderByDescending(p => p.ItemVotes.Select(x => x.TypeVote).Sum(predicate)).ToList();   
} 

在您的来电,你可以选择通过这样的服务:

Func<bool, int> getPositiveVotedItemsFirst = (vote) => vote ? 1 : -1; 

var itemsOrderedByPositiveVotes = _ItemsService.GetOrderedItems(getHighlyVotedItems); 

您现在可以轻松地获得项目由至少下令投的,只是通过改变你的选择。

Func<bool, int> getLeastVotedItemsFirst = (vote) => !vote ? 1 : -1; 

var itemsOrderedByNegativeVotes = _ItemsService.GetOrderedItems(getLeastVotedItemsFirst);