简体   繁体   English

实体框架-加入列表

[英]Entity Framework - Join to a List

I need to retrieve a list of entities from my database that matches a list of items in a plain list (not EF). 我需要从数据库中检索与简单列表(不是EF)中的项目列表匹配的实体列表。 Is this possible with Entity Framework 4.1? Entity Framework 4.1是否可以实现?

Example: 例:

var list = new List<string> { "abc", "def", "ghi" };
var items = from i in context.Items
            where list.Contains(i.Name)
            select i;

This works great to return rows that match one property, but I actually have a more complex property: 返回匹配一个属性的行效果很好,但实际上我有一个更复杂的属性:

var list = new List<Tuple<string, string>>
{
    new Tuple<string,string>("abc", "123"),
    new Tuple<string,string>("def", "456")
};

// i need to write a query something like this:
var items = from i in context.Items
where list.Contains(new Tuple<string,string>(i.Name, i.Type))
select i;

I know that is not valid because it will say it needs to be a primitive type, but is there any way to do what I'm trying to accomplish or will I need to resort to a stored procedure? 我知道这是无效的,因为它将说它必须是原始类型,但是有什么方法可以完成我要完成的工作,还是需要诉诸存储过程?

You need to break it down to sub-properties. 您需要将其细分为子属性。 For example, something like (this might not compile, i'm not able to test at the moment, but it should give you something to work with): 例如,类似的东西(可能无法编译,目前我无法测试,但是应该可以使用):

var items = from i in context.Items 
where list.Select(x => x.Item1).Contains(i.Name) 
   && list.Select(x => x.Item2).Contains(i.Type)
select i; 

You have a few options: 您有几种选择:

1) You could, of course, write a stored procedure to do what you need and call it. 1)当然,您可以编写存储过程来执行所需的操作并调用它。

2) You could read the table into memory and then query the in memory list...that way you don't have to use primitives: 2)您可以将表读入内存中,然后查询内存中列表...这样就不必使用原语了:

var items = from i in context.Items.ToList()
            where list.Contains(new Tuple<string, string>(i.Name, i.Type))
            select i;

3) You could also convert your query to use primitives to achieve the same goal: 3)您也可以将查询转换为使用基元来实现相同的目标:

 
 
 
 
  
  
  var items = from i in context.Items join l in list on new { i.Name, i.Type } equals new { Name = l.Item1, Type = l.Item2 } select i;
 
 
  

I would go with the second option as long as the table isn't extremely large. 只要表不是很大,我就会选择第二个选项。 Otherwise, go with the first. 否则,请选择第一个。

You have to think about what the resulting SQL would look like, this would be difficult to do directly in SQL. 您必须考虑生成的SQL的外观,这很难直接在SQL中完成。

My suggestion would be you split out one field of the tuples and use this to cut down the results list, get back the query result then filter again to match one of the tuples eg 我的建议是将元组的一个字段拆分出来,并使用它来缩减结果列表,返回查询结果,然后再次过滤以匹配其中一个元组,例如

var list = new List<string> { "abc", "def" };
var list2 = new List<Tuple<string, string>>
{
  new Tuple<string,string>("abc", "123"),
  new Tuple<string,string>("def", "456")
};
var items = (from i in context.Items
        where list.Contains(i.Name)
        select i)
        .AsEnumerable()
        .Where(i => list2.Any(j => j.val1 == i.Name && j.val2 == i.Type);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM