【问题标题】:The xml data type cannot be selected as DISTINCT because it is not comparable errorxml 数据类型不能选为 DISTINCT,因为它是不可比较的错误
【发布时间】:2012-02-23 19:10:53
【问题描述】:

我的代码中有此查询我收到此错误。

 var auditMandate = (from ae in genDB.AuditEvent
                     join at in genDB.AuditTable on // snip
                     select ae)
                     .OrderByDescending(x => 
                         x.DateTime_Updated).Take(500)
                     .Distinct().ToList();

执行命令定义时出错。有关详细信息,请参阅内部异常。
xml 数据类型不能选择为 DISTINCT,因为它不可比较。 xml 数据类型无法选择为 DISTINCT,因为它不可比较。

这是我在这个 Linq 做错了什么吗?

谢谢

【问题讨论】:

  • xml数据类型不能选择为DISTINCT,因为它没有可比性
  • 我认为你的问题是xml数据类型不能选择为DISTINCT,因为它没有可比性。
  • 看起来您正在尝试对不可比较的类型集合调用 DISTINCT,您知道... xml 数据类型。
  • 它是可行的,你只需要解决它。看我的回答。性能是另一个问题,我没有考虑 Take(500) 但你会明白的:-)

标签: asp.net asp.net-mvc linq asp.net-mvc-3 linq-to-sql


【解决方案1】:

这是可行的。接受您的查询,但摆脱 Distinct 呼叫。但是,您仍然需要一个具体的列表,因此请保留 ToList()。然后按照这个思路(因为我不知道你的xml结构):

我的桌子

CREATE TABLE [dbo].[XmlTable](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [data] [xml] NULL
)

我的数据

insert into XmlTable
values('<list id=''a''><items></items></list>')
insert into XmlTable
values('<list id=''b''><items></items></list>')
insert into XmlTable
values('<list id=''a''><items></items></list>')

我的比较器

    public class MyXDocumentCoparer : IEqualityComparer<XDocument>
    {
        public bool Equals(XDocument x, XDocument y)
        {
            var xId = x.Root.Attribute("id").Value;
            var yId = y.Root.Attribute("id").Value;
            return xId == yId;
        }

        public int GetHashCode(XDocument obj)
        {
            var id = obj.Root.Attribute("id").Value;
            return id.GetHashCode();
        }
    }

我的代码

    using (var ctx = new xmltestEntities())
    {
        // this would be your concrete list
        var rawData = ctx.XmlTables.ToArray();

        var processedData = rawData
            .Select(row => XDocument.Parse(row.data))
            .Distinct(new MyXDocumentCoparer());

        // you'll only get two, boom!
        foreach (var item in processedData)
            Console.WriteLine(item.Root.Attribute("id"));

        Console.ReadLine();
    }

【讨论】:

    【解决方案2】:

    您正在尝试选择不同的 AuditEvents,但您的 LINQ 提供程序不知道如何确定两个 AuditEvents 是否相同。考虑投影到一个知道如何进行这种比较的类中。另一种选择是使用 GroupBy 根据特定属性生成不同的项目:

    .GroupBy(ae => ae.Id).Select(g => g.First());
    

    附带说明一下,在调用 Take 之前进行不同的检查通常更有意义,因此即使原始集合中的前 500 个项目包含重复项,您仍将获得多达 500 个项目。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多