C# 用于重新构造数据的LINQ组嵌套列表
我有一个自定义对象的嵌套列表,它作为JSON从服务传递,我需要将其重新构造为一个新对象。以下是嵌套列表包含的对象:C# 用于重新构造数据的LINQ组嵌套列表,c#,linq,C#,Linq,我有一个自定义对象的嵌套列表,它作为JSON从服务传递,我需要将其重新构造为一个新对象。以下是嵌套列表包含的对象: public class Alt { public Member Member { get; set; } public Claim OriginalClaim { get; set; } public Claim AltClaim { get; set; } public double Savings { get; set; } } 对于每个成员
public class Alt
{
public Member Member { get; set; }
public Claim OriginalClaim { get; set; }
public Claim AltClaim { get; set; }
public double Savings { get; set; }
}
对于每个成员和OriginalClaim,可以有一个或多个AltClaim。所以我要做的是得到每个成员/原始客户的所有AltClaim。我要将数据映射到的新对象如下所示:
public class Alternative
{
public Member Member { get; set; }
public Claim OriginalClaim { get; set; }
public List<AlternativeClaim> AlternativeClaims { get; set; }
}
public class AlternativeClaim
{
public Claim AltClaim { get; set; }
public double Savings { get; set; }
}
公共类替代方案
{
公共成员成员{get;set;}
公共声明OriginalClaim{get;set;}
public List是我使用的LINQ查询,但我无法在没有它的情况下将内容正确分组。在我分组所依据的类上实现IEquatable是关键
非常感谢大家!您在这个问题上的帮助教会了我很多。尝试备选方案。选择many(alt=>new{alt.Member,alt.OriginalClaim})
给出输出:
Auth 51
MemberId 50
Savings = 696969;Id = 513;
Savings = 6969;Id = 512;
Savings = 69;Id = 511;
Auth 52
MemberId 50
Savings = 1002;Id = 522;
Savings = 100;Id = 521;
Auth 102
MemberId 100
Savings = 1022;Id = 1022;
Savings = 1021;Id = 1021;
测试代码
[Test]
public void Test()
{
var member1 = new Member {Id = 50};
var member1Claim1 = new Claim {Id = 51};
var member1Claim2 = new Claim {Id = 52};
var member2 = new Member { Id = 100 };
var member2Claim1 = new Claim { Id = 101 };
var member2Claim2 = new Claim { Id = 102 };
var alternatives = new List<List<Alt>>()
{
new List<Alt>
{
new Alt
{
Member = member1,
OriginalClaim = member1Claim1,
AltClaim = new Claim {Id = 511},
Savings = 69
},
new Alt
{
Member = member1,
OriginalClaim = member1Claim1,
AltClaim = new Claim {Id = 512},
Savings = 6969
},
new Alt
{
Member = member1,
OriginalClaim = member1Claim1,
AltClaim = new Claim {Id = 513},
Savings = 696969
},
new Alt
{
Member = member1,
OriginalClaim = member1Claim2,
AltClaim = new Claim {Id = 521},
Savings = 100
},
new Alt
{
Member = member1,
OriginalClaim = member1Claim2,
AltClaim = new Claim {Id = 522},
Savings = 1002
}
},
new List<Alt>
{
new Alt
{
Member = member2,
OriginalClaim = member2Claim2,
AltClaim = new Claim {Id = 1021},
Savings = 1021
},
new Alt
{
Member = member2,
OriginalClaim = member2Claim2,
AltClaim = new Claim {Id = 1022},
Savings = 1022
}
}
};
}
[测试]
公开无效测试()
{
var member1=新成员{Id=50};
var member1Claim1=新索赔{Id=51};
var member1Claim2=新索赔{Id=52};
var member2=新成员{Id=100};
var member2Claim1=新索赔{Id=101};
var member2Claim2=新索赔{Id=102};
var alternations=新列表()
{
新名单
{
新Alt
{
成员=成员1,
原始Claim=成员1 Claim1,
AltClaim=新索赔{Id=511},
储蓄=69
},
新Alt
{
成员=成员1,
原始Claim=成员1 Claim1,
AltClaim=新索赔{Id=512},
储蓄=6969
},
新Alt
{
成员=成员1,
原始Claim=成员1 Claim1,
AltClaim=新索赔{Id=513},
储蓄=696969
},
新Alt
{
成员=成员1,
原始Claim=成员1 Claim2,
AltClaim=新索赔{Id=521},
储蓄=100
},
新Alt
{
成员=成员1,
原始Claim=成员1 Claim2,
AltClaim=新索赔{Id=522},
节省=1002
}
},
新名单
{
新Alt
{
成员=成员2,
OriginalClaim=member2Claim2,
AltClaim=新索赔{Id=1021},
储蓄=1021
},
新Alt
{
成员=成员2,
OriginalClaim=member2Claim2,
AltClaim=新索赔{Id=1022},
节省=1022
}
}
};
}
为了完整性:
public class Alt
{
public Member Member { get; set; }
public Claim OriginalClaim { get; set; }
public Claim AltClaim { get; set; }
public double Savings { get; set; }
}
public class Claim
{
public int Id { get; set; }
}
public class Member
{
public int Id { get; set; }
}
public class Alternative
{
public Member Member { get; set; }
public Claim OriginalClaim { get; set; }
public List<AlternativeClaim> AlternativeClaims { get; set; }
}
public class AlternativeClaim
{
public Claim AltClaim { get; set; }
public double Savings { get; set; }
}
公共类Alt
{
公共成员成员{get;set;}
公共声明OriginalClaim{get;set;}
公共声明AltClaim{get;set;}
公共双储蓄{get;set;}
}
公共类索赔
{
公共int Id{get;set;}
}
公共班级成员
{
公共int Id{get;set;}
}
公共类替代方案
{
公共成员成员{get;set;}
公共声明OriginalClaim{get;set;}
公共列表可选声明{get;set;}
}
公共类替代索赔
{
公共声明AltClaim{get;set;}
公共双储蓄{get;set;}
}
您的成员和索赔类是否实现了IEquatable
如果没有,我怀疑分组不起作用,因为成员实例和声明实例正在通过引用进行比较。而且,由于您提到您以JSON的形式从服务接收数据,您的所有ALT很可能都有不同的成员实例和声明实例。因此,它们永远不会属于同一组,即使它们的属性没有他有同样的价值观
要使分组正常工作,可以执行以下操作之一:
如果可用,请从Member and Claim and group by it中选择唯一标准(如id或名称):
var test = from alts in alternatives
from alt in alts
group alts by new { MemberId = alt.Member.Id, OriginalClaimId = alt.OriginalClaim.Id } into a
select a;
foreach (var a in test)
{
Console.WriteLine("Auth {0}", a.Key.OriginalClaimId);
Console.WriteLine("MemberId {0}", a.Key.MemberId);
foreach (var alt in a.SelectMany(x => x))
[write out alt.AltClaim properties in console here]
}
为您的会员和索赔实施IEquatable和IEquatable
public class Member : IEquatable<Member>
{
public bool Equals(Member other)
{
return Id == other.Id;
}
public override bool Equals(object obj)
{
var other = obj as Member;
if (other == null)
return false;
return Equals(other);
}
public override int GetHashCode()
{
// Whenever IEquatable is implemented, GetHashCode() must also be overridden.
return Id.GetHashCode();
}
// Rest of the class...
}
公共类成员:IEquatable
{
公共布尔等于(其他成员)
{
返回Id==other.Id;
}
公共覆盖布尔等于(对象对象对象)
{
var other=作为成员的obj;
如果(其他==null)
返回false;
回报等于(其他);
}
公共覆盖int GetHashCode()
{
//无论何时实现IEquatable,都必须重写GetHashCode()。
返回Id.GetHashCode();
}
//其他同学。。。
}
我想,这是一个打字错误,应该是group alts
,也应该是group alt
?简单的选择而不是selectmany。你可以展示一些备选方案的例子吗?为什么是列表列表?@MichalCiechan你的答案中包含了一些基本的备选方案。至于为什么是嵌套列表,这只是服务返回的结果。基本allyList
被发送,服务返回所发送列表中每个元素的List
。不幸的是,它很复杂。我正在摆弄我的代码,试图让它正常工作。这似乎是正确的,但我的结果不是你得到的结果,而是每个成员和原始Claim只能得到一个备选索赔,所以它是pri为每个备选索赔提取成员/原始索赔数据。我会继续处理这些数据,并让您知道我是否成功。我做了,但我感觉从服务中得到的嵌套列表可能会出现一些奇怪的情况。关键是,您需要对备选方案执行SelectMany操作,以便将收集的数据展平这是一种罪恶
var test = from alts in alternatives
from alt in alts
group alts by new { MemberId = alt.Member.Id, OriginalClaimId = alt.OriginalClaim.Id } into a
select a;
foreach (var a in test)
{
Console.WriteLine("Auth {0}", a.Key.OriginalClaimId);
Console.WriteLine("MemberId {0}", a.Key.MemberId);
foreach (var alt in a.SelectMany(x => x))
[write out alt.AltClaim properties in console here]
}
public class Member : IEquatable<Member>
{
public bool Equals(Member other)
{
return Id == other.Id;
}
public override bool Equals(object obj)
{
var other = obj as Member;
if (other == null)
return false;
return Equals(other);
}
public override int GetHashCode()
{
// Whenever IEquatable is implemented, GetHashCode() must also be overridden.
return Id.GetHashCode();
}
// Rest of the class...
}