LINQ to SQL:将2列排序到一个新列中

LINQ to SQL:将2列排序到一个新列中,linq,Linq,我有一个包含名称和公司名称的表的数据库。它们是互斥的(任一字段都为空)。使用LINQ to SQL,我试图将这两个列彼此“排序”(但不在内存中,我希望SQL Server 2008能够完成此操作),这样我就可以得到一个单独的列“DisplayName”,它将执行以下操作: Record Name CompanyName 1 Smith NULL 2 Fields NULL 3 NULL Mi

我有一个包含
名称
公司名称
的表的数据库。它们是互斥的(任一字段都为空)。使用LINQ to SQL,我试图将这两个列彼此“排序”(但不在内存中,我希望SQL Server 2008能够完成此操作),这样我就可以得到一个单独的列“DisplayName”,它将执行以下操作:

Record     Name       CompanyName
     1     Smith      NULL
     2     Fields     NULL
     3     NULL       Microsoft
     4     Zian       NULL
     5     NULL       Gibbons
Record     DisplayName
     2     Fields
     5     Gibbons
     3     Microsoft
     1     Smith
     4     Zian

我的输出应该是

Record     Name       CompanyName
     1     Smith      NULL
     2     Fields     NULL
     3     NULL       Microsoft
     4     Zian       NULL
     5     NULL       Gibbons
Record     DisplayName
     2     Fields
     5     Gibbons
     3     Microsoft
     1     Smith
     4     Zian

请注意输出是如何跨两个源列排序的。这需要支持分页(跳过和执行)。你知道怎么做吗

感谢spender,我现在有了这个:

剩下的问题是:如何仍然只返回原始域对象?上面查询中引入的匿名类型现在抛出返回类型错误的错误(必须保持(
IQueryable
)。快到了?!。。基本上,我需要找到一种方法,在查询期间将排序为的“DisplayName”值分配给原始对象。

编辑:

db
.Table
.Select(t=>new{t.Record,DisplayName=t.Name??t.CompanyName})
.OrderBy(t.DisplayName); 
将创建类似以下内容的SQL:

SELECT [t1].[Record], [t1].[DisplayName]
FROM (
    SELECT 
        [t0].[Record], 
        COALESCE([t0].[Name],[t0].[CompanyName]) AS [DisplayName]
    FROM [Table] AS [t0]
    ) AS [t1]
ORDER BY [t1].[DisplayName]
这看起来满足了您的要求。您可以很高兴地将Skip添加到这个语句的末尾,以支持分页

说明年份(根据评论):

最后一个要求非常简单,只需编写一个新类来封装结果:

public class Result
{
    public int Record
    {
        get;
        set;
    }

    public string DisplayName
    {
        get;
        set;
    }
}
然后查询将变成:

db
.Table
.Where(t=>t.Year>1990)
.Select(t=>new Result{t.Record,DisplayName=t.Name??t.CompanyName})
.OrderBy(t.DisplayName); 
但是,我开始认为,如果要创建SQL查询的视图:

SELECT [t1].[Record], [t1].[DisplayName],[t1].[Year]
FROM (
    SELECT 
        [t0].[Record], 
        COALESCE([t0].[Name],[t0].[CompanyName]) AS [DisplayName],
        [t0.Year]
    FROM [Table] AS [t0]
    ) AS [t1]
ORDER BY [t1].[DisplayName]
然后将此视图拖到Dbml曲面上,可能会获得更好的效果

编辑:

如果可以的话,最佳方法是如下更改源表,以便DisplayName成为源位置的计算列

ALTER TABLE [Table]
    ADD [DisplayName] As 
    (COALESCE([Name],[CompanyName]))
我终于明白了你的问题(我不知道DisplayName只是为了订购,不需要维护)。以下是您的疑问:

db
.Table
.Where(t=>t.Year>1990)
.Select(t=>new {Item=t,DisplayName=t.Name??t.CompanyName})
.OrderBy(a=>a.DisplayName)
.Select(a=>a.Item);
塔达

编辑:

db
.Table
.Select(t=>new{t.Record,DisplayName=t.Name??t.CompanyName})
.OrderBy(t.DisplayName); 
将创建类似以下内容的SQL:

SELECT [t1].[Record], [t1].[DisplayName]
FROM (
    SELECT 
        [t0].[Record], 
        COALESCE([t0].[Name],[t0].[CompanyName]) AS [DisplayName]
    FROM [Table] AS [t0]
    ) AS [t1]
ORDER BY [t1].[DisplayName]
这看起来满足了您的要求。您可以很高兴地将Skip添加到这个语句的末尾,以支持分页

说明年份(根据评论):

最后一个要求非常简单,只需编写一个新类来封装结果:

public class Result
{
    public int Record
    {
        get;
        set;
    }

    public string DisplayName
    {
        get;
        set;
    }
}
然后查询将变成:

db
.Table
.Where(t=>t.Year>1990)
.Select(t=>new Result{t.Record,DisplayName=t.Name??t.CompanyName})
.OrderBy(t.DisplayName); 
但是,我开始认为,如果要创建SQL查询的视图:

SELECT [t1].[Record], [t1].[DisplayName],[t1].[Year]
FROM (
    SELECT 
        [t0].[Record], 
        COALESCE([t0].[Name],[t0].[CompanyName]) AS [DisplayName],
        [t0.Year]
    FROM [Table] AS [t0]
    ) AS [t1]
ORDER BY [t1].[DisplayName]
然后将此视图拖到Dbml曲面上,可能会获得更好的效果

编辑:

如果可以的话,最佳方法是如下更改源表,以便DisplayName成为源位置的计算列

ALTER TABLE [Table]
    ADD [DisplayName] As 
    (COALESCE([Name],[CompanyName]))
我终于明白了你的问题(我不知道DisplayName只是为了订购,不需要维护)。以下是您的疑问:

db
.Table
.Where(t=>t.Year>1990)
.Select(t=>new {Item=t,DisplayName=t.Name??t.CompanyName})
.OrderBy(a=>a.DisplayName)
.Select(a=>a.Item);

塔达

使用LINQ to SQL并不能回答您的问题,但是最好创建一个视图,并使用COALESCE操作符从Name或CompanyName中选择第一个非空值

使用LINQ to SQL并不能回答您的问题,但是最好创建一个视图,并使用COALESCE操作符从Name或CompanyName中选择第一个非空值

在最初的帖子中提到这一点可能会更好。已经提供了可以实现此目的的替代语句。您的语句失败的原因是您正在对不再包含“Year”的集合执行“Where”子句。它只包含“记录”和“显示名称”。重新排序语句就可以了。我认为最好在新问题中继续这样做:)我更新了问题。。我想这也是其中的一部分:)谢谢你迄今为止的帮助!!!!我需要保持返回类型相同(IQueryable),因为查询随后可能会使用其他IQueryable扩展方法进行增强。我唯一能做的就是向域对象添加一个新属性并动态分配给它(而不是新的匿名类型+属性)。这可能吗?最好在原始帖子中提到这一点。已经提供了可以实现此目的的替代语句。您的语句失败的原因是您正在对不再包含“Year”的集合执行“Where”子句。它只包含“记录”和“显示名称”。重新排序语句就可以了。我认为最好在新问题中继续这样做:)我更新了问题。。我想这也是其中的一部分:)谢谢你迄今为止的帮助!!!!我需要保持返回类型相同(IQueryable),因为查询随后可能会使用其他IQueryable扩展方法进行增强。我唯一能做的就是向域对象添加一个新属性并动态分配给它(而不是新的匿名类型+属性)。可能吗?