2

我正在使用 Linq to Entities 和 Entity Framework 编写查询。我的应用程序使用两个数据库。由于客户需求,跨数据库不是一个选项。

假设MyEntity驻留在第一个数据库中(所以它在一个 EF 模型上)并且它引用了第二个数据库中的一个实体SecondDBEntity(所以它在另一个 EF 模型上),它有一个复合键。现在,假设我想检索所有MyEntity引用一组SecondDBEntity(在我们的示例中,具有键 [1, 1]、[1, 2] 和 [1, 3] 的实体)的所有引用。

我要生成的 SQL 是这样的:

SELECT *
  FROM MyEntity
 WHERE (MyEntity.ForeignKeyOne = 1 AND MyEntity.ForeignKeyTwo = 1)
    OR (MyEntity.ForeignKeyOne = 1 AND MyEntity.ForeignKeyTwo = 2)
    OR (MyEntity.ForeignKeyOne = 1 AND MyEntity.ForeignKeyTwo = 3)

然后我尝试了以下代码:

var setOfEntitiesToSearch = LetsAssumeThisIsAnIEnumerableOfSecondDBEntity;
return (from myEntity in DataContext.MyEntityList
       where setOfEntitiesToSearch.Any(entityToSearch => entityToSearch.KeyOne == myEntity.ForeignKeyOne && entityToSearch.KeyTwo == myEntity.ForeignKeyTwo)
      select myEntity).ToList();

这段代码编译得很好,但是当我执行时,它给了我错误:

"Unable to create a constant value of type 'SecondDBEntity'. Only primitive types or enumeration types are supported in this context."

我的主要问题是因为实体位于不同的数据库中。我可能在做一些愚蠢的事情,因为这是我正在尝试构建的一个非常常见的查询。所以,我相信我缺少 EF 中的一些功能,这将允许我创建这个查询。也许是一些 CompositeKey 结构?或者以某种方式混合这些 EF 模型?

提前致谢。

4

2 回答 2

0

首先创建两个列表

var listKeyOne = setOfEntitiesToSearch.Select(e => e.KeyOne);
var listKeyTwo = setOfEntitiesToSearch.Select(e => e.KeyTwo);

然后使用这些列表,例如

return (from myEntity in DataContext.MyEntityList
       where listKeyOne.Any(keyOne => myEntity.ForeignKeyOne == keyOne) &&
             listKeyTwo.Any(keyTwo => myEntity.ForeignKeyTwo == keyTwo)
      select myEntity).ToList();

这使问题变得更加微不足道。请让我知道它是否有效

于 2012-10-06T22:19:03.963 回答
0

Linq 无法将 setOfEntitiesToSearch 转换为 sql 查询。它只能使用原始类型。请注意,IEnumerable 与枚举不同。Linq 可以使用枚举,因为它可以转换为整数类型的值,但它不能将 IEnumerable 转换为原始类型。

据我所知,您可以采用两种不同的方式。(注意,我在没有编译的情况下输入了这段代码,所以它可能需要调试。)

1)循环通过 setOfEntitiesToSearch 并建立一个这样的列表:

List<MyEntity> results = new List<MyEntity>();
foreach (item in setOfEntitiesToSearch) {
    results.AddRange(
        from myEntity in DataContext.MyEntityList           
        where myEntity.ForeignKeyOne == item.KeyOne && myEntity.ForeignKeyTwo == item.KeyTwo
        select myEntity).ToList()
    );
}
return results;

2) 将所有 DataContext.MyEntityList 放入内存列表并查询。

var entityList = DataContext.MyEntityList.ToList()
return entityList.Where(myEntity => setOfEntitiesToSearch.Any(entityToSearch => entityToSearch.KeyOne == myEntity.ForeignKeyOne && entityToSearch.KeyTwo == myEntity.ForeignKeyTwo)).ToList()

缺点 #1 - 在循环中调用数据库。

缺点 #2 - entityList 可能非常大,具体取决于 DataContext.MyEntityList 返回的项目数。

于 2012-10-06T22:27:58.090 回答