gpt4 book ai didi

c# - LINQ Select Distinct 忽略 XML 字段

转载 作者:数据小太阳 更新时间:2023-10-29 01:47:48 25 4
gpt4 key购买 nike

我有一个复杂的 LINQ 查询(使用 LINQ 2 EF)可以返回重复的结果,因此我使用 .Distinct() 方法来避免重复。这是骨架:

var subQuery1 = // one query...
var subQuery2 = // another query...
var result = subQuery1.Distinct().Union( subQuery2.Distinct() ).ToArray();

每个子查询将一个公共(public)用户表与另一个表连接起来并执行“where”查询,结果随后在 .Union(...) 中合并。在表被修改为包含一个 XML 列之前,这一直工作得很好,这导致了这个异常:

the xml data type cannot be selected as distinct because it is not comparable

在这种情况下,我不关心 XML 列在结果中是否相同。实际上我只需要确保主键 UserId 在结果中是不同的。

有没有办法使用 Distinct() 但忽略 XML 列或更简单的方法来确保我从结果中删除具有相同 UserId 的记录有效的方法?理想情况下,这不会从数据库中检索重复记录,也不需要后处理来删除重复项。

更新:我发现,如果我提前将查询序列化为数组,那么就不需要任何类型的比较器,因为 Linq2Objects 没有 XML 不同选择问题。例如我可以这样做:

var subQuery1 = // one query...
var subQuery2 = // another query...
var result =
subQuery1.Distinct().ToArray().Union(
subQuery2.Distinct().ToArray() )
.ToArray();

所以我真正想要的是一种避免序列化中间查询并直接执行 Linq2Entities 调用的方法,该调用不会获取具有重复 UserId 的记录。感谢您到目前为止的所有回答。

最佳答案

写一个IEqualityComparer<T>包含您的 XML 类型的对象的实现并将其传递给 Distinct .在Equals方法,您可以根据需要实现相等语义。

这是我自己编写的一个方便的 T4 代码生成模板,用于生成 IEqualityComparer<T>我团队领域模型的实现:

<#@ template language="C#v3.5" debug="True" #>
<#@ output extension=".generated.cs" #>
<#
var modelNames = new string[] {
"ClassName1",
"ClassName2",
"ClassName3",
};

var namespaceName = "MyNamespace";
#>
using System;
using System.Collections.Generic;

namespace <#= namespaceName #>
{
<#
for (int i = 0; i < modelNames.Length; ++i)
{
string modelName = modelNames[i];
string eqcmpClassName = modelName + "ByIDEqualityComparer";
#>
#region <#= eqcmpClassName #>

/// <summary>
/// Use this EqualityComparer class to determine uniqueness among <#= modelName #> instances
/// by using only checking the ID property.
/// </summary>
[System.Diagnostics.DebuggerNonUserCode]
public sealed partial class <#= eqcmpClassName #> : IEqualityComparer<<#= modelName #>>
{
public bool Equals(<#= modelName #> x, <#= modelName #> y)
{
if ((x == null) && (y == null)) return true;
if ((x == null) || (y == null)) return false;

return x.ID.Equals(y.ID);
}

public int GetHashCode(<#= modelName #> obj)
{
if (obj == null) return 0;

return obj.ID.GetHashCode();
}
}

#endregion
<#
if (i < modelNames.Length - 1) WriteLine(String.Empty);
} // for (int i = 0; i < modelNames.Length; ++i)
#>
}

它假设您的每个模型类都有一个名为“ID”的属性,它是主键,存储为实现 Equals 的东西。我们的惯例强制我们所有的模型都具有此属性。如果您的模型都具有不同名称的 ID 属性,请考虑修改此 T4 模板以满足您的需求或更好,让您的生活更轻松(不仅仅是为了使用此 T4)并更改您的模型以使用“ID "名字。

关于c# - LINQ Select Distinct 忽略 XML 字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3929620/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com