过滤列表<t> .Contains </t>

时间:2014-05-11 18:24:25

标签: entity-framework entity-framework-6 dbcontext

我需要通过确定传递给方法的参数在列表中来过滤LINQ查询。我用另一个项目做了类似的事情,它工作正常,但我不能在这里得到语法。

首先,我根据传递给方法的值创建一个列表:

// Create a list of category events here
var categoryList = new List<int>();
var categories = context.CategoryEvents
    .Where(c => c.CategoryId == categoryId)
    .Select(c => c.CategoryId);
if(categoryList.Any())
{
    categoryList.AddRange(categories);
}

接下来,我创建了一个查询,我需要根据参数是否在列表中来过滤结果:

events = context.Events
    .Where(categoryList.Contains(categoryId)) // Doesn't work

1 个答案:

答案 0 :(得分:0)

代码存在一些问题。

  1. 您按CategoryId过滤后选择CategoryId。您的意思是选择EventId来代替吗?
  2. if(categoryList.Any())应为if(categories.Any())
  3. .Where(categoryList.Contains(categoryId))
  4. 中需要有一个lambda表达式

    这里是修改后的代码版本,有更好的工作机会......

    var eventIdList = new List<int>();
    var eventIds = context.CategoryEvents
        .Where(c => c.CategoryId == categoryId)
        .Select(c => c.EventId);
    if(eventIds.Any())
    {
        eventIdList.AddRange(eventsIds);
    }
    
    var eventsInCategory = context.Events
        .Where(e => eventIdList.Contains(e.EventId)); // or simply e.Id, depending on what your model looks like
    

    如果可行,可以采取很多措施来改进/简化代码。

    例如,此if块实际执行两个数据库查询,一次用于Any(),另一次用于AddRange() ...

    if(eventIds.Any())
    {
        eventIdList.AddRange(eventsIds);
    }
    

    您实际上可以使用ToList()替换第一个代码块。不需要new List<int>()Any()AddRange() ...

    var eventIdList = context.CategoryEvents
        .Where(c => c.CategoryId == categoryId)
        .Select(c => c.EventId)
        .ToList();
    

    听起来你正在试图用这整段代码来查找给定CategoryId中的所有事件。您可以在1个EF查询中执行此操作...

    var eventsInCategory = context.Events
        .Join(context.CategoryEvents,
              e => e.EventId, // or simply e.Id, depending on what your model looks like
              ce => ce.EventId,
              (e, ce) => e)
        .ToList();
    

    如果使用正确的导航属性设置模型,则可以进一步简化此操作。例如,如果您有Categories DbSet并且它具有所有相关Event的导航属性:

    var eventsInCategory = context.Categories.Find(categoryId).Events;