【发布时间】:2013-03-25 09:24:20
【问题描述】:
我有一个这样创建的匿名对象集合:
var srcCategories = srcSet.Categories.Select(c => new
{
ApplicationId = c.IsGLobal ? (long?)null : c.App.Id,
c.Name
});
请注意,此集合不是来自我的数据上下文;它是从外部系统的输入生成的。我需要将 both ApplicationId 和 Name 与我数据库中的实体进行映射。到目前为止,这是我能够成功使其工作的唯一方法:
var trgCategoryIds =
(from c in core.Domain.Categories.AsEnumerable()
let ci = new { c.ApplicationId, c.Name }
where srcCategories.Contains(ci)
select c.Id)
.ToArray();
但这需要我先将整个Categories 表拉入内存。我正在寻找一种更有效的方法来执行此操作,最好是在单个查询中。以下选项我都试过了,都不能转sql:
// Removed .AsEnumerable()
var trgCategoryIds =
(from c in core.Domain.Categories
let ci = new { c.ApplicationId, c.Name }
where srcCategories.Contains(ci)
select c.Id)
.ToArray();
// Use .Any() instead of .Contains()
var trgCategoryIds =
(from c in core.Domain.Categories
where srcCategories.Any(s => s.ApplicationId == c.ApplicationId && s.Name == s.Name)
select c.Id)
.ToArray();
// Use Tuples instead of anon types
var srcCategories = srcSet.Categories.Select(c => Tuple.Create(...));
var trgCategoryIds =
(from c in core.Domain.Categories
let ci = Tuple.Create(c.ApplicationId, c.Name)
where srcCategories.Contains(ci)
select c.Id)
.ToArray();
【问题讨论】:
-
这是两个不同的数据库,还是一个数据库?两个
Categories集合是否来自同一个DataContext? -
@Servy 不,
srcCategories源自外部系统的输入 - 具体而言,Web 服务公开了一个类别列表,然后根据命令行参数对其进行过滤。跨度> -
那么,如果两个 IQueryable 来自不同的来源,您将如何避免将两个数据集之一拉入内存?两人几乎肯定不知道如何交谈。
-
@Servy - 按照我的阅读方式,第一个数据源实际上是无关紧要的 - 在我们到达第二个数据库之前,它变成了一个对象,它是
string/long对。所以它只是将内存中的对象列表与数据库进行比较。 -
.Contains方法转换为 sqlIN运算符。要匹配 sql 中的列,您必须创建和填充表变量,然后加入。这基本上就是我想做的,除非有更好的选择。
标签: c# linq entity-framework contains anonymous-types