使用左连接获得不适当的输出
我正在尝试获取变体列表,并且对于每个变体都获取所有subvariants list
而不管子变量在哪里落入特定Test say 100
这是样本数据:
Id TestId SourceSubVariantId TargetSubVariantId DiffPerc 114 100 66 67 100.00 115 100 67 68 100.00 116 100 70 71 99.99
变体1有3个子变量 :
Id=66,Name=Abc Id=68,Name=Pqr Id=69,Name=xyz
变体2有3个子变量 :
Id=70,Name=lmn Id=71,Name=xxx Id=72,Name=hhh
但是在我的输出中注意到Variant1 CustomSubvariantList
Variants 2
subvariants list
所有Id as 0
:
数据模型:
public class Variants { public int Id { get; set; } public string Name { get; set; } public string Type { get; set; } public virtual ICollection SubVariants { get; set; } } public class SubVariants { public int Id { get; set; } public int VariantId { get; set; } public string Name { get; set; } public virtual Variants Variants { get; set; } public virtual ICollection TestOperation { get; set; } public virtual ICollection TestOperation1 { get; set; } } public class TestOperation { public int Id { get; set; } public Nullable TestId { get; set; } public int SourceSubVariantId { get; set; } public int TargetSubVariantId { get; set; } public decimal DiffPerc { get; set; } public virtual SubVariants SubVariants { get; set; } public virtual SubVariants SubVariants1 { get; set; } public virtual Test Test { get; set; } }
查询:
int testId=100; var query = from v in context.Variants where v.Type == "Add" select new { ParentVariant = v.Name, Type = v.Method, CustomSubvariantList = ( from svName in context.SubVariants.Select(sv => sv.Name).Distinct() join x in ( from sv in v.SubVariants from to in sv.TestOperation where to.TestId == testId orderby sv.Id select new { sv.Name, to.DiffPerc, SourceId = (int?)to.SubVariants.Id, TargetID=(int?)to.SubVariants1.Id } ) on svName equals x.Name into g from x in g.DefaultIfEmpty() orderby x.SourceId select new { SourceId=x.SourceId ?? 0, TargetId=x.TargetID ?? 0, Name = svName, DiffPerc = x.DiffPerc } ).ToList() };
更新: 根据评论,这是样本输入和预期输出:
情况1 : 当所有父变体中的子变量名称不同时
变种:
Id Name Type CategoryId 11 Variant1 Add 1 12 Variant2 Add 1 13 Variant3 Add 1 14 Variant4 Add 1
子变体:
Id VariantId Name 66 11 Abc 67 11 PQR 68 11 Xyz 70 12 lmn 71 12 xxx 72 12 hhh
测试操作:
Id TestId SourceSubVariantId TargetSubVariantId DiffPerc 114 100 66 67 10.00 115 100 67 68 20.00 114 100 70 71 40.00 115 100 71 72 50.00
预期产量 :
情况2 : 当所有父变体中的子变量名称相同时:
子变体:
Id VariantId Name 66 11 Abc 67 11 PQR 68 11 Xyz 70 12 Abc 71 12 PQR 72 12 Xyz
预期产出 :
我们有一些关于聊天的讨论,直到我明白你想要什么。
这是代码:
class Program { static void Main(string[] args) { VariantsEntities db=new VariantsEntities(); var queryResult = db.Variants.AsEnumerable().Select(x => new PageViewModel { ParentVariant = x.Name, Type = x.Type, CustomSubvariantList = GetCustomSubVariants(x.Id,db).ToList() }).ToList(); var jsonObj = JsonConvert.SerializeObject(queryResult); Console.WriteLine(jsonObj); Console.ReadKey(); } private static IEnumerable GetCustomSubVariants(int variantId, VariantsEntities db) { var subVariants = db.SubVariants.ToList(); foreach (var subVariant in subVariants) { var obj=new Customsubvariantlist(); obj.Name = subVariant.Name; var testOpTarget = db.TestOperations .FirstOrDefault(x => x.TargetSubVariantId == subVariant.Id); var testOpSource = db.TestOperations .FirstOrDefault(x => x.SourceSubVariantId == subVariant.Id); if (subVariant.VariantId == variantId) { obj.Value = testOpTarget == null ? testOpSource?.SourceValue : testOpTarget?.TargetValue; obj.DiffPerc = testOpTarget?.DiffPerc; } else { obj.Value = null; obj.DiffPerc = null; } yield return obj; } } }
你只需要替换DbContext名称,然后测试它。
这是结果:
[ { "ParentVariant": "Variant1", "Type": "Add", "CustomSubvariantList": [ { "Name": "Abc", "Value": 200, "DiffPerc": null }, { "Name": "Pqr", "Value": 300, "DiffPerc": 100.0 }, { "Name": "xyz", "Value": 500, "DiffPerc": 200.0 }, { "Name": "lmn", "Value": null, "DiffPerc": null }, { "Name": "xxx", "Value": null, "DiffPerc": null }, { "Name": "hhh", "Value": null, "DiffPerc": null } ] }, { "ParentVariant": "Variant2", "Type": "Add", "CustomSubvariantList": [ { "Name": "Abc", "Value": null, "DiffPerc": null }, { "Name": "Pqr", "Value": null, "DiffPerc": null }, { "Name": "xyz", "Value": null, "DiffPerc": null }, { "Name": "lmn", "Value": 1000, "DiffPerc": null }, { "Name": "xxx", "Value": 2000, "DiffPerc": 1000.0 }, { "Name": "hhh", "Value": 4000, "DiffPerc": 2000.0 } ] } ]
从这里您可以下载示例项目。 这个项目是用你发给我的样本数据库完成的,所以是数据库优先,有些道具或表可能有不同的名字,请在项目中移动代码之前检查一下。
基本上我做了什么:
-
创建了一个新的控制台app项目
-
我从你的json对象中获取了模型(我复制了json对象并将其放在一个类中,使用(vs菜单)Edit – > Past Special – > Past JSON as Classes。
-
由于你想要每个
Varian
所有SubVariants
,我创建了一个单独的方法来处理你创建CustomSubVariantList
的规则。 在这个方法中,我迭代抛出所有SubVariants,我根据你的条件创建了对象。
更新:您的解决方案在一个查询中:
static void Main(string[] args) { VariantsEntities db = new VariantsEntities(); var result = from x in db.Variants select new PageViewModel { ParentVariant = x.Name, Type = x.Type, CustomSubvariantList = (from z in db.SubVariants let testOpTarget=z.TestOperations1 .FirstOrDefault(q=>q.TargetSubVariantId==z.Id) let testOpSource=z.TestOperations .FirstOrDefault(q=>q.SourceSubVariantId==z.Id) select new Customsubvariantlist { Name = z.Name, Value = x.Id==z.VariantId? testOpTarget.TargetValue?? testOpSource.SourceValue:null, DiffPerc = x.Id==z.VariantId? testOpTarget.DiffPerc:null }).ToList() }; var json = JsonConvert.SerializeObject(result.ToList()); Console.WriteLine(json); Console.ReadKey(); }
此查询产生与上述方法相同的结果。 如果您需要,请告诉我!
更新:这是案例2的查询
var result = from x in db.Variants select new PageViewModel { ParentVariant = x.Name, Type = x.Type, CustomSubvariantList = (from z in db.SubVariants.GroupBy(g => g.Name) .Select(g => g.FirstOrDefault(d => d.VariantId == x.Id) ?? g.FirstOrDefault()) let testOpTarget = z.TestOperations1 .FirstOrDefault(q => q.TargetSubVariantId == z.Id) let testOpSource = z.TestOperations .FirstOrDefault(q => q.SourceSubVariantId == z.Id) select new Customsubvariantlist { Name = z.Name, SubVariantId = z.Id, CombineName =(z.TestOperations.Any() || z.TestOperations1.Any())? testOpTarget.TargetValue.HasValue? testOpTarget.SubVariant.Name+" to "+testOpTarget.SubVariant1.Name : null: "Undefined", Value = x.Id == z.VariantId ? testOpTarget.TargetValue ?? testOpSource.SourceValue : null, DiffPerc = x.Id == z.VariantId ? testOpTarget.DiffPerc : null }).OrderBy(k => k.SubVariantId).ToList() };
这是您的查询的“变体”..它提取了每个Variant(s)
所有SubVariants
,因为它们在表SubVariants中(通过其自动化的Sql Server Identity Id),不管涉及的TestOperation
如何,并避免重复作为您的预期输出。
遗憾的是,不可能始终将所有子变量指定为source和tartget子变量,因为此信息取决于testoperation,实际上testop决定子变量是“source”还是“target”。 因此,如果某些子变量未包含在testoperations记录/实体中,那么它们就不能作为源或目标出现..一种解决方法可能是附加,在返回的匿名类型的“Name”属性旁边,也是“Id SubVar”
我添加了2个DTO,因为entity framework不允许使用distinct().ToList()
方法来保留顺序并应用自定义的不同规则,所以我添加了一个步骤,通过dto对象在链接到对象的链接到EF传递这种方式可以应用不同的自定义规则。
public class CustomerVariantDTO { public String Type; public String ParentVariant; public IEnumerable CustomSubvariantList; } public class CustomerSubVariantDTO { public int? VariantId; public int? SubVariantId; public int? SourceId; public int? TargetId; public String Name; public Decimal? DiffPerc; } sealed class CustomerSubVariantDTOComparer : IEqualityComparer { public int GetHashCode(CustomerSubVariantDTO obj) { return 0; } public bool Equals(CustomerSubVariantDTO x, CustomerSubVariantDTO y) { return x.SourceId == y.SourceId && x.TargetId == y.TargetId && x.Name == y.Name && x.DiffPerc == y.DiffPerc; } } public void DoTestOfCustomerVariantDTO() { int testId = 1; using (var context = new VariantsEntities()) { var query = (from v in context.Variants where v.Type == "Add" select new CustomerVariantDTO { ParentVariant = v.Name, Type = v.Type, CustomSubvariantList = ( from sv in context.SubVariants.Select(sv => sv) join x in ( from svparent in v.SubVariants from to in svparent.TestOperation where to.TestId == testId select new { svparent.Name, to.DiffPerc, SourceId = (int?)to.SubVariants.Id ?? 0, TargetId = (int?)to.SubVariants1.Id ?? 0 } ) on sv.Name equals x.Name into g from x in g.DefaultIfEmpty() select new CustomerSubVariantDTO{ VariantId = sv.VariantId, SubVariantId = sv.Id, SourceId = (int?)x.SourceId ?? sv.TestOperation.Select(to => to.SourceSubVariantId).FirstOrDefault(), TargetId = (int?)x.TargetId ?? sv.TestOperation.Select(to => to.TargetSubVariantId).FirstOrDefault(), Name = sv.Name, DiffPerc = x.DiffPerc } ).OrderBy(csv => new { csv.VariantId, csv.SubVariantId }) }).ToList(); var listCustomVariants = query.Select(v => new{ Type = v.Type, ParentVariant = v.ParentVariant, CustomSubvariantList = v.CustomSubvariantList.Distinct(new CustomerSubVariantDTOComparer()).ToList() }); foreach (var item in listCustomVariants){ Console.WriteLine($"Type: {item.Type} - ParentVariant: {item.ParentVariant} "); foreach (var csubvar in item.CustomSubvariantList) Console.WriteLine($"SourceId: {csubvar.SourceId} - TargetiId: {csubvar.TargetId} - NAme: {csubvar.Name} - DiffPerc: {csubvar.DiffPerc} "); } } }
- 如何在保持到目前为止生成的堆栈跟踪的同时重新抛出内部exception?
- 如何强制可本地化的WinForms应用程序使用(默认)语言属性
- 管理CheckedListBox ItemCheck事件,以便在之前检查的项目之后运行
- 如何使用ASP.NET动态创建文本框,然后将其值保存在数据库中?
- IIS 7.x,添加启用HTTPS的站点:SiteCollection.Add(string,string,string,byte )重载
- WP8应用中的付款
- C#.NET:如何检查我们是否使用电池运行?
- 使用Micorsoft.Office.Interop(对象库)通过IIS 7读取word doc时出错
- 哪种控制更适合下面显示的输出?