使用左连接获得不适当的输出

Lea*_*sed 18 c# linq entity-framework left-join

我正在尝试获取变体列表,并且对于每个变体都可以获得所有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
Run Code Online (Sandbox Code Playgroud)

变体13个子变量:

Id=66,Name=Abc
Id=68,Name=Pqr
Id=69,Name=xyz
Run Code Online (Sandbox Code Playgroud)

变体23个子变量:

Id=70,Name=lmn
Id=71,Name=xxx
Id=72,Name=hhh
Run Code Online (Sandbox Code Playgroud)

但是,在我的输出注意到我得到的所有Id as 0Variants 2 subvariants listVariant1 CustomSubvariantList:

在此输入图像描述

数据模型:

public class Variants
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Type { get; set; }
        public virtual ICollection<SubVariants> 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> TestOperation { get; set; }
        public virtual ICollection<TestOperation> TestOperation1 { get; set; }
    }

        public class TestOperation
    {
        public int Id { get; set; }
        public Nullable<int> 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; }
    }
Run Code Online (Sandbox Code Playgroud)

查询:

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()
         };
Run Code Online (Sandbox Code Playgroud)

更新: 根据评论,这是样本输入和预期输出:

情况1:当所有父变体中的子变量名称不同时

变种:

Id      Name       Type   CategoryId
11      Variant1    Add     1
12      Variant2    Add     1
13      Variant3    Add     1
14      Variant4    Add     1
Run Code Online (Sandbox Code Playgroud)

子变体:

Id     VariantId     Name
66      11           Abc
67      11           PQR
68      11           Xyz

70      12           lmn
71      12           xxx
72      12           hhh
Run Code Online (Sandbox Code Playgroud)

测试操作:

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
Run Code Online (Sandbox Code Playgroud)

预期产量: 在此输入图像描述

情况2:当所有父变体中的子变量名称相同时:

子变体:

Id     VariantId     Name
66      11           Abc
67      11           PQR
68      11           Xyz

70      12           Abc
71      12           PQR
72      12           Xyz
Run Code Online (Sandbox Code Playgroud)

预期产出:

Luc*_*umb 6

我们有一些关于聊天的讨论,直到我明白你想要什么.

这是代码:

    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<Customsubvariantlist> 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;
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

你只需要替换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
      }
    ]
  }
]
Run Code Online (Sandbox Code Playgroud)

这里您可以下载示例项目.这个项目是使用您发送给我的示例数据库完成的,因此是数据库优先,并且某些道具或表可能具有不同的名称,请在移动项目中的代码之前检查此项目.

基本上我做了什么:

  1. 创建了一个新的控制台app项目

  2. 我从你的json对象中获取了模型(我复制了json对象并将它放在一个类中,使用(vs菜单)Edit - > Past Special - > Past JSON as Classes.

  3. 因为你想要SubVariants每个人都有Varian,所以我创建了一个单独的方法来处理你创建的规则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();
    }
Run Code Online (Sandbox Code Playgroud)

此查询产生与上述方法相同的结果.如果您需要,请告诉我!

更新:这是案例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()
            };
Run Code Online (Sandbox Code Playgroud)