获取具有一组特定子元素的项目(高级查询 - 可能吗?)

时间:2008-10-30 20:47:25

标签: visual-studio-2008 linq linq-to-sql .net-3.5

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

ITEM

  • ID(Int,Identity)
  • 姓名(NVarChar(50))
  • 描述(NVarChar(200))

META

  • ID(Int,Identity)
  • 姓名(NVarChar(50))

这两者之间存在N-N关系,即Item可以包含零个或多个元引用,meta可以与多个项相关联。每个元数据只能与同一个项目关联一次。这意味着我在中间有经典表

ITEMMETA

  • ItemID(Int)
  • MetaID(Int)

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

  • 汽车
  • 福特
  • 越野

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

  • 我将有一个Meta标签列表,我想用它来过滤将要返回的项目(例如上面的示例我有Car,Ford和Offroad)
  • 一个项目可以拥有与我在比赛中提供的更多元项目,即如果一个项目有Car,Ford,Offroad和Red关联它,那么在过滤器中提供它们的任意组合应该会产生匹配
  • 但是,过滤器中提供的所有元名必须与一个项相关联,以便在结果集中返回它。所以发送汽车,福特,越野和红色不应该与汽车,福特和越野(没有红色)相关的项目匹配

我希望清楚我想要实现的目标,我觉得我没有像我希望的那样清晰= /让我们希望它足够了:)。

谢谢!

3 个答案:

答案 0 :(得分:2)

这应该适合你:

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;

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

答案 1 :(得分:1)

这会带回任何符合任何元标准的内容,然后将其过滤为仅符合所有条件的内容。 (另外,请记住,您需要在datacontext中定义关系)。如果您需要澄清,请告诉我们。

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);

答案 2 :(得分:1)

您可以通过计算过滤的元数来过滤项目。

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,我永远不会记住)。