Linq to sql 为什么LINQ to SQL会在Select中省略列

Linq to sql 为什么LINQ to SQL会在Select中省略列,linq-to-sql,Linq To Sql,我正在使用LINQtoSQL来选择记录。我需要将两个查询合并在一起,但select语句正在更改,因此表达式不再匹配,从而阻止合并 此LINQ查询将从最终结果中忽略强制列“resultType”和“imageFile” var taglist = from t in dc.ProductTags where t.Tag.StartsWith(prefixText) select new AutoSearch { resultType = "Tag", name =

我正在使用LINQtoSQL来选择记录。我需要将两个查询合并在一起,但select语句正在更改,因此表达式不再匹配,从而阻止合并

此LINQ查询将从最终结果中忽略强制列“resultType”和“imageFile”

var taglist = from t in dc.ProductTags
 where t.Tag.StartsWith(prefixText)
 select new AutoSearch { 
      resultType = "Tag", 
      name = t.Tag, 
      imageFile = string.Empty, 
      urlElement = t.Tag };
这是显示的查询

{SELECT [t0].[Tag] AS [name] FROM [dbo].[ProductTag] AS [t0] WHERE [t0].[Tag] LIKE @p0}
这是与初始查询联合的第二个查询

var brandlist = from b in dc.Businesses
                    join t in dc.Tags on b.BusinessId equals t.BusinessId
                    where b.Name.StartsWith(prefixText)
                    where b.IsActive == true
                    where t.IsActive == true
                        select new AutoSearch
                        { 
                        resultType = "Business", 
                        name = b.Name, 
                        imageFile = t.AdImage, 
                        urlElement = b.BusinessId.ToString() };
这是第二个查询的sql

SELECT [t0].[Name] AS [name], [t1].[AdImage] AS [imageFile], CONVERT(NVarChar(MAX) [t0].[BusinessId]) AS [urlElement] FROM [dbo].[Business] AS [t0] INNER JOIN [dbo].[Tag] AS [t1] ON ([t0].[BusinessId]) = [t1].[BusinessId] WHERE ([t0].[Name] LIKE @p0)
工会。。。这就产生了错误

var unionedResults = taglist.Union(brandlist);
错误被抛出

使用UNION、INTERSECT或EXCEPT运算符组合的所有查询在其目标列表中的表达式数必须相等

这是自动搜索类

    public class AutoSearch
    {
    public string name { get; set; }
    public string imageFile { get; set; }
    public string resultType { get; set; }
    public string urlElement { get; set; }
    }
关于正在发生什么的建议

更新***

找到了一份工作

发现了问题

这是LINQ中的一个已知错误,在这里找到了一些讨论,为我指明了正确的方向。事实证明,网站上列出的大多数解决方案都不再有效,因为4.0版也破坏了它们。我找到了另一个有效的

出于优化目的,LINQ省略了重复的值。我可以通过将废弃字段转换为字符串或小写或串联来更改它们的值

效率极低,但它能工作。我在这件事上浪费了一整天,也许这会节省别人的时间

            var taglist = from t in dc.ProductTags
                      where t.Tag.StartsWith(prefixText)
                      let resultType = "Tag"
                      select new AutoSearch() {
                          resultType = resultType, 
                          name = t.Tag,
                          imageFile = t.Tag.ToString(),
                          urlElement = t.Tag.ToLower()
                      };

        var brandlist = from b in dc.Businesses
                    join t in dc.Tags on b.BusinessId equals t.BusinessId
                    where b.Name.StartsWith(prefixText)
                    where b.IsActive == true
                        where t.IsActive == true
                        where t.AdImage != null
                        where t.AdImage != String.Empty
                        let resultType = "Business"
                        select new AutoSearch
                        {
                            resultType = resultType, 
                            name = b.Name, 
                            imageFile = t.AdImage, 
                            urlElement = b.BusinessId.ToString()
                        };

在执行查询的select部分时,您引用的唯一属性是Tag,Linq to Sql知道这一点,并将查询优化为仅选择您正在引用的列

换句话说,查询的这一部分只引用“Tag”属性,该属性绑定到数据库上的Tag列

new AutoSearch { 
  resultType = "Tag", 
  name = t.Tag, 
  imageFile = string.Empty, 
  urlElement = t.Tag };
在这种情况下,Linq所做的是将表达式传递给底层提供程序(非常类似于二叉树数据结构)。然后,提供程序解析此树,并在运行时从中创建SQL查询。优化由提供程序在运行时完成,这将导致您看到的SQL查询

更新

对于联合的第二个问题,您基本上是试图联合两个不同的SQL语句,这导致了联合错误。让我们来看看

将导致错误的结果语句如下所示

SELECT [t0].[Tag] AS [name] FROM [dbo].[ProductTag] AS [t0] WHERE [t0].[Tag] LIKE @p0
UNION
SELECT [t0].[Name] AS [name], [t1].[AdImage] AS [imageFile], CONVERT(NVarChar(MAX) [t0].[BusinessId]) AS [urlElement] FROM [dbo].[Business] AS [t0] INNER JOIN [dbo].[Tag] AS [t1] ON ([t0].[BusinessId]) = [t1].[BusinessId] WHERE ([t0].[Name] LIKE @p0)
显然,这是有问题的,因为这两个列之间的列数不一样,而且SQL也不支持这一点。虽然我没有一个纯linq解决方案,但有一个变通方法

首先您需要创建一个SQL函数,只返回发送给它的字符串

CREATE FUNCTION ReturnString( @string varchar(max) )
RETURNS varchar(max)
AS
BEGIN
    RETURN @string
END
GO
接下来将这个新的SQL函数拖放到dbml文件中,最后在查询中只需在适当的地方调用该方法

var taglist = from t in dc.ProductTags
                where t.Tag.StartsWith(prefixText)
                select new AutoSearch
                {
                    resultType = dc.ReturnString("Tag"),
                    name = t.Tag,
                    imageFile = dc.ReturnString(string.Empty),
                    urlElement = dc.ReturnString(t.Tag)
                };

var brandlist = from b in dc.Businesses
                join t in dc.Tags on b.BusinessId equals t.BusinessId
                where b.Name.StartsWith(prefixText)
                where b.IsActive == true
                where t.IsActive == true
                select new AutoSearch
                {
                    resultType = dc.ReturnString("Business"),
                    name = b.Name,
                    imageFile = t.AdImage,
                    urlElement = b.BusinessId.ToString()
                };

现在您应该能够执行联合了。

可能是因为这是您引用的
标记的唯一属性?或者,它应该每次查询所有列(甚至是巨大的列)吗?在您的监视窗口中使用此选项查看发生了什么:
((System.Data.Objects.ObjectQuery)myLinqQueryVar。)ToTraceString()
。是的,我知道。。。这就是为什么这是一个评论,嗯?对不起,我不太明白。我可能需要添加结果集中的所有项,因为我要将此查询与其他查询合并。我计划将其合并到此查询。。。因此,我需要选择中的所有项目都可用`var brandlist=from b in dc.Businesses join t in dc.b.BusinessId上的标记等于t.BusinessId,其中b.Name.StartsWith(prefixText)选择新建自动搜索{resultType=“Business”,Name=b.Name,imageFile=t.AdImage,urlement=b.BusinessId.ToString()};'当我尝试将标记列表合并到品牌列表时。。。我得到这个错误。var unionedResults=taglist.Union(brandlist);“”“使用UNION、INTERSECT或EXCEPT运算符组合的所有查询在其目标列表中的表达式数必须相等。”“”如果问题有第二部分,请编辑问题并添加第二部分和相关代码。