LINQ to SQL:将2列排序为新列

时间:2009-09-15 08:08:39

标签: linq

我的数据库包含一个包含NameCompanyName的表格。它们是互斥的(字段为空)。使用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 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 DisplayName 2 Fields 5 Gibbons 3 Microsoft 1 Smith 4 Zian

剩下的问题是:我怎样才能仅返回原始域对象?上面查询中引入的匿名类型现在抛出返回类型错误的错误(必须保留(

db
.Table
.Where(t=>t.Year>1990)
.Select(t=>new{t.Record,DisplayName=t.Name??t.CompanyName})
.OrderBy(t.DisplayName);
))。几乎在那里?!..基本上我需要找到一种方法来分配在查询过程中为原始对象排序的“DisplayName”值。

2 个答案:

答案 0 :(得分:3)

编辑:

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和Take到本声明的末尾来支持分页。

考虑年份(根据评论):

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

您最后的要求就像编写一个新类来封装结果一样简单:

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);

TADA!

答案 1 :(得分:0)

这不是使用LINQ to SQL回答您的问题,但创建VIEW并使用COALESCE运算符从Name或CompanyName中选择firt非null值可能更好。