代码之家  ›  专栏  ›  技术社区  ›  TheCodeJunkie

正在获取具有特定子元素集的项(是否可以进行高级查询?)

  •  2
  • TheCodeJunkie  · 技术社区  · 16 年前

    我有一个SQL数据库(SQL Server 2008),其中包含以下设计

    项目

    • ID(int,标识)
    • 姓名(nvarchar(50))
    • 说明(nvarchar(200))

    • ID(int,标识)
    • 姓名(nvarchar(50))

    这两者之间存在N-N关系,即一个项可以包含零个或多个元引用,一个元可以与多个项关联。每个元只能与同一项关联一次。这意味着我中间有一张经典的桌子

    ITMeta

    • ItemID(int)
    • 元辅助(int)

    我想执行LinqToSQL查询来提取包含一组特定元链接的所有项实体。例如,给我所有与之相关联的元项

    • 小型车
    • 福特
    • 欧罗

    是否可以在LinqToSQL的帮助下编写这样的查询?让我再提出一些要求

    • 我将有一个元标签列表,我想使用它来过滤将要返回的项目(例如在上面的例子中,我有汽车、福特和越野车)
    • 一个项目可以有比我在比赛中提供的更多的元项目,即如果一个项目有汽车,福特,越野和红色关联到它,那么在过滤器中提供它们的任何组合应该会导致一个匹配
    • 但是,过滤器中提供的所有元名称都必须与要在结果集中返回的项关联。因此,送车、福特、越野和红色不应该是与汽车、福特和越野(没有红色)相关联的物品的匹配。

    我希望我正在努力实现的目标是明确的,我觉得我没有我希望的那么清楚=/让我们希望它足够了:)

    谢谢您!

    3 回复  |  直到 16 年前
        1
  •  2
  •   Lucas    16 年前

    这应该对你有用:

    string[] criteria = new[] { "Car", "Ford", "Offroad" };
    
    var items = 
        from i in db.Item
        let wantedMetas = db.Meta.Where(m => criteria.Contains(m.Name))
        let metas = i.ItemMeta.Select(im => im.Meta)
        where wantedMetas.All(m => metas.Contains(m))
        select i;
    

    基本上,它将“需要的”元与每个项目的元进行比较,并选择具有所有需要的元(或更多)的项目。

        2
  •  1
  •   Andrew Theken Tan Li Hau    16 年前

    这将返回与任何元条件匹配的任何内容,然后将其筛选为仅与所有条件匹配的内容。(另外,请记住,您需要在数据上下文中定义您的关系)。如果需要澄清,请通知我们。

    var db = new YourDataContext();
    var possibleItems = (from m in db.Metas where <meta criteria> select m.ItemMetas.Item);
    
    var items = possibleItems.GroupBy(y=>y).Where(x=>x.Count() == criteriaCount).Select(x=>x.Key);
    
        3
  •  1
  •   Amy B    16 年前

    您可以通过计算筛选后的元来筛选项目。

    List<string> metaList = new List<string>() { "Car", "Ford", "Offroad" };
    int metaListCount = metaList.Count;
    List<Item> result =
      db.Items
      .Where(i => metaListCount ==
        i.ItemMeta.Meta
        .Where(m => metaList.Contains(m.Name))
        .Count()
      )
      .ToList();
    

    请注意,此内存中集合有一个上限。包含由sqlserver的参数限制所施加的(它是~200或~2000,我永远记不起来)。