【问题标题】:What is the equivalent DISTINCT(sql server) in the LinqLinq 中的等效 DISTINCT(sql server) 是什么
【发布时间】:2013-07-22 06:25:25
【问题描述】:

我有一个包含列(Id、UserId、SendDate)的表(发送)和另一个包含列(Id、SendId、用户名)的表(接收)。

我想在 SendTable 中显示所有带有 RecieveUserName 的记录。

例如。

(Send)
1   1   2013
2   2   2013


(Recieve)
1   1   Jack
2   1   Ema
3   2   Alex
4   2   Sara


Result
1   1   2013  Jack, Ema
2   2   2013  Alex, Sara

我在SqlServer 中使用此查询(DISTINCT 关键字从 SELECT 语句的结果中消除重复行)

SELECT DISTINCT c2.Id,
(SELECT    STR( UserName )+ ','
 FROM         dbo.Reciver c1
 WHERE     c1.SendId = c2.id FOR XML PATH('')) Concatenated, c2.SendDate, c2.UserId
 FROM         dbo.Send AS c2 INNER JOIN
 dbo.Reciver ON c2.Id = dbo.Reciver.SendId

如何在 Linq 中查询?

【问题讨论】:

  • 您能否展示如何在没有“distinct”的情况下使用 LINQ 执行此操作?我问是因为我怀疑给你带来问题的是“不同的”。
  • 我在 sql server 中使用这个查询。我想在 linq 中找到它的等价物。
  • 那么请编辑您的问题摘要,这样您就不会只询问如何翻译“distinct”。

标签: sql linq


【解决方案1】:

Distinct 也可以在LINQ 中使用。

例如

public class Product
{
    public string Name { get; set; }
    public int Code { get; set; }
}

Product[] products = { new Product { Name = "apple", Code = 9 }, 
                   new Product { Name = "orange", Code = 4 }, 
                   new Product { Name = "apple", Code = 10 }, 
                   new Product { Name = "lemon", Code = 9 } };
var lstDistProduct = products.Distinct();
foreach (Product p in list1)
{
    Console.WriteLine(p.Code + " : " + p.Name);
}

将返回所有行。

var list1 = products.DistinctBy(x=> x.Code);

foreach (Product p in list1)
{
    Console.WriteLine(p.Code + " : " + p.Name);
}

将返回 9 和 4

【讨论】:

  • 谢谢,但我在 SqlServer 中使用了这个查询。 DISTINCT 关键字从 SELECT 语句的结果中消除重复行
  • DistinctBy 不是标准 linq。
【解决方案2】:

在我看来,您不需要在此 Linq 查询中使用 Distinct。假设您在 linq 数据上下文中设置了表之间的关系,您可以执行以下操作:

var result = from s in context.Send
             select new {
                 id = s.Id,
                 userId = s.UserId,
                 date = s.SendDate,
                 users = s.Receive.Select(u => u.UserName)
             }

注意:users 将是一个 IEnumerable<String> - 您可以在客户端上使用 string.Join() 将名称连接成一个字符串。

更新

要将用户作为字符串返回,首先需要通过调用AsEnumerable()ToList() 和Linq to Sql 查询“切换”到Linq To Objects。

var output = from s in result.AsEnumerable()
             select new {
                 id = s.id,
                 userId = s.userId,
                 date = s.date,
                 users = string.Join(", ", s.users)
             }

另请参阅Gert Arnolds answer 以获得很好的解释。

【讨论】:

  • 谢谢,我可以使用字符串(用户)而不是用户列表( users = s.Receive.Select(u => u.UserName)) 将所有用户名加入字符串吗?
  • 您可以尝试string.Join(",", s.Receive.Select(u => u.UserName)),但您可能会收到无法翻译成sql的错误。在这种情况下,您必须遍历结果并在客户端执行string.Join。例如,不在您的 linq 被翻译成的 sql select 语句中。
  • 谢谢,是的,我收到错误 this method cannot be translated into a store expression. 。如何解决?
【解决方案3】:

你想要的只能分两步完成。不是因为DISTINCT,而是因为FOR XML。后者的 C# 等效项是 String.Join(),但您不能直接在 linq to entity 语句中使用它。所以你必须先收集所需的数据,然后切换到 linq 到对象(通过应用 AsEnumerable),然后进行连接和区分:

 db.Sends
   .Where(s => s.Receivers.Any())
   .Select(s => new { 
                       s.Id, 
                       Concatenated = s.Receivers.Select(r => r.UserName)
                       s.SendDate,
                       s.UserId
                    })
   .AsEnumerable()
   .Select(x => new { 
                       s.Id, 
                       Concatenated = String.Join(", ", x.Concatenated)
                       s.SendDate,
                       s.UserId
                    })
   .Distinct()

【讨论】:

    猜你喜欢
    • 2010-11-19
    • 2011-01-10
    • 2020-03-02
    • 2015-09-14
    • 2021-09-17
    • 1970-01-01
    • 2011-01-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多