Linq Union:如何为查询添加文字值?

时间:2011-01-20 19:59:23

标签: c# linq union

我需要为查询添加文字值。我的尝试

var aa = new List<long>();
aa.Add(0);
var a = Products.Select(p => p.sku).Distinct().Union(aa);

a.ToList().Dump(); // LinqPad's way of showing the values

在上面的例子中,我收到一个错误:

"Local sequence cannot be used in LINQ to SQL implementation
of query operators except the Contains() operator."

例如,如果我使用Entity Framework 4,我可以添加到Union语句中以便始终包含“种子”ID吗?

我正在尝试生成如下代码的SQL代码:

select distinct ID
from   product
union
select 0 as ID

所以稍后我可以join列表给自己,这样我就能找到下一个最高值不存在的所有值(找到集合中最低的可用ID)。

编辑:原始Linq查询以查找最低可用ID

var skuQuery = Context.Products
               .Where(p => p.sku > skuSeedStart && 
                           p.sku < skuSeedEnd)
               .Select(p => p.sku).Distinct();

var lowestSkuAvailableList = 
    (from p1 in skuQuery
     from p2 in skuQuery.Where(a => a == p1 + 1).DefaultIfEmpty()
     where p2 == 0  // zero is default for long where it would be null
     select p1).ToList();
var Answer = (lowestSkuAvailableList.Count == 0 
              ? skuSeedStart : 
              lowestSkuAvailableList.Min()) + 1;

此代码创建两个偏移一的SKU集,然后选择下一个不存在的SKU。之后,它选择最小值(最低SKU可用下一个最高值)。

为此,种子必须在一起连接在一起。

3 个答案:

答案 0 :(得分:4)

您的问题是您的查询完全转换为LINQ-to-SQL查询,而您需要的是LINQ-to-SQL查询,并在其上进行本地操作。

解决方案是告诉编译器在处理查询后要使用LINQ-to-Objects (换句话说,更改扩展方法的分辨率以查看IEnumerable<T>,不是IQueryable<T>)。最简单的方法是将AsEnumerable()添加到查询的末尾,如下所示:

var aa = new List<long>();
aa.Add(0);
var a = Products.Select(p => p.sku).Distinct().AsEnumerable().Union(aa);

a.ToList().Dump(); // LinqPad's way of showing the values

答案 1 :(得分:1)

预先:没有回答你问的问题,而是以不同的方式解决你的问题。

这个怎么样:

var a = Products.Select(p => p.sku).Distinct().ToList();

a.Add(0);

a.Dump(); // LinqPad's way of showing the values

答案 2 :(得分:0)

您应该创建用于存储常量值的数据库表,并将查询从此表传递给Union运算符。

例如,让我们想象表“Defaults”,其中“Name”和“Value”字段只有一条记录(“SKU”,0)。

然后你可以像这样重写你的表达式:

        var zero = context.Defaults.Where(_=>_.Name == "SKU").Select(_=>_.Value);
        var result = context.Products.Select(p => p.sku).Distinct().Union(zero).ToList();