【问题标题】:How to change the linq query to get 3 records with unique Id如何更改 linq 查询以获取 3 条具有唯一 ID 的记录
【发布时间】:2021-06-16 20:01:33
【问题描述】:

此查询返回 4 条记录(2x 是 IdStandard = 2) - 我需要 3 条具有唯一 IdStandard 和 PrimaryCalcMethod 和 SecondaryCalcMethod 方法的记录。如果后一种方法不存在,SecondaryCalcMethod 属性将返回 null。如何更改 linq 查询?

 public List<StandardEnt> ListStandardsWithMethodList()
        {
            var listModel =
                (
                from dane in _dbContext.Standard
                join kraj in _dbContext.CountryStandard
                on dane.IdCountryStandard equals kraj.IdCountryStandard
                join opcja in _dbContext.MeasureDiameterOption
                on dane.IdStandard equals opcja.IdStandard
                join metoda in _dbContext.MeasureDiameterMethod
                on opcja.IdMeasureDiameterMethod equals metoda.IdMeasureDiameterMethod
                join sposob in _dbContext.WalkingLineRadius
                on opcja.IdWalkingLineRadius equals sposob.IdWalkingLineRadius
                join linia in _dbContext.CalcMethodType
                on sposob.IdCalcMethodType equals linia.IdCalcMethodType
                join wyznaczanie in _dbContext.WalkingLineMeasure
                on sposob.IdWalkingLineMeasure equals wyznaczanie.IdWalkingLineMeasure
                select new StandardEnt()
                {
                    IdStandard = dane.IdStandard,
                    IdCountryStandard = dane.IdCountryStandard,
                    StandardName = dane.StandardName,
                    IsActive = dane.IsActive,
                    NameCountry = kraj.NameCountryStandard,
                    FreeHeadSpace = (double)dane.FreeHeadSpace,
                    IsTlcStandard = dane.IsTlcStandard,
                    MinLandingSize = (double)dane.MinLandingSize,
                    MinStepHeight = (double)dane.MinStepHeight,
                    MaxStepHeight = (double)dane.MaxStepHeight,
                    MinConvinience = (double)dane.MinConvinience,
                    MaxConvinience = (double)dane.MaxConvinience,
                    MaxStepDeep = (double)dane.MaxStepDeep,
                    MinStepDeep = (double)dane.MinStepDeep,
                    MaxStepWidth = (double)dane.MaxStepWidth,
                    WidthLimit = (double)dane.WidthLimit,
                    StartOverlap = (double)dane.StartOverlap,
                    InternalHandrailMaxRadius = (double)dane.InternalHandrailMaxRadius,
                    PrimaryCalcMethod = (from metody in _dbContext.MeasureDiameterOption
                                         where dane.IdStandard == metody.IdStandard && metody.MeasureDiameterMethod.CalcMethodName == "PrimaryCalcMethod"
                                         select new MeasureDiameterMethodEnt()
                                         {
                                             IdMeasureDiameterOption = opcja.IdMeasureDiameterOption,
                                             Description = opcja.Description,
                                             IdMeasureDiameterMethod = metoda.IdMeasureDiameterMethod,
                                             IdWalkingLineRadius = sposob.IdWalkingLineRadius,
                                             IdCalcMethodType = linia.IdCalcMethodType,
                                             IdWalkingLineMeasure = wyznaczanie.IdWalkingLineMeasure,
                                             //CalcMethod = Enum.Parse<DiamDivide>(linia.CalcMethodNameType),
                                             //WalkingLineMeasure = Enum.Parse<WalkingLineMeasureMethod>(wyznaczanie.WalkingLineMeasureName),
                                             CalcMethodName = metoda.CalcMethodName,
                                             FirstWidth = (double)sposob.FirstWidth,
                                             SecondWidth = (double)sposob.SecondWidth
                                         }).FirstOrDefault(),
                    SecondaryCalcMethod = (from metody in _dbContext.MeasureDiameterOption
                                           where dane.IdStandard == metody.IdStandard && metody.MeasureDiameterMethod.CalcMethodName == "SecondaryCalcMethod"
                                           select new MeasureDiameterMethodEnt()
                                           {
                                               IdMeasureDiameterOption = opcja.IdMeasureDiameterOption,
                                               Description = opcja.Description,
                                               IdMeasureDiameterMethod = metoda.IdMeasureDiameterMethod,
                                               IdWalkingLineRadius = sposob.IdWalkingLineRadius,
                                               IdCalcMethodType = linia.IdCalcMethodType,
                                               IdWalkingLineMeasure = wyznaczanie.IdWalkingLineMeasure,
                                               //CalcMethod = Enum.Parse<DiamDivide>(linia.CalcMethodNameType),
                                               //WalkingLineMeasure = Enum.Parse<WalkingLineMeasureMethod>(wyznaczanie.WalkingLineMeasureName),
                                               CalcMethodName = metoda.CalcMethodName,
                                               FirstWidth = (double)sposob.FirstWidth,
                                               SecondWidth = (double)sposob.SecondWidth
                                           }).FirstOrDefault()
                }
            ).ToList();
            return listModel;
        }

并生成 Json 下面我以 Json 格式发送结果 - 因此您可以看到 IdStandard 为法国国家/地区返回了两次

[
    {
        "idStandard": 1,
        "idCountryStandard": 2,
        "idMeasureDiameterOption": 0,
        "description": null,
        "idMeasureDiameterMethod": 0,
        "idWalkingLineRadius": 0,
        "idCalcMethodType": 0,
        "idWalkingLineMeasure": 0,
        "standardName": "Szwecja TLC Standard",
        "isActive": true,
        "freeHeadSpace": 2100.0,
        "isTlcStandard": true,
        "minLandingSize": 800.0,
        "minStepHeight": 160.0,
        "maxStepHeight": 240.0,
        "minConvinience": 590.0,
        "maxConvinience": 660.0,
        "maxStepDeep": null,
        "minStepDeep": null,
        "widthLimit": null,
        "primaryCalcMethod": {
            "calcMethodName": "PrimaryCalcMethod",
            "walkingLineMeasure": 0,
            "calcMethod": 0,
            "firstWidth": 300.0,
            "secondWidth": 0.0,
            "idMeasureDiameterOption": 1,
            "description": "od krawędzi zewnętrznej 300mm",
            "idMeasureDiameterMethod": 1,
            "idWalkingLineRadius": 1,
            "idCalcMethodType": 1,
            "idWalkingLineMeasure": 2
        },
        "secondaryCalcMethod": null,
        "maxStepWidth": null,
        "startOverlap": 10.0,
        "endOverlap": 0.0,
        "walkLineOverlap": 0.0,
        "internalHandrailMaxRadius": 131.0,
        "maxStepsAmount": 0,
        "nameCountry": "Szwecja",
        "calcMethodName": null,
        "walkingLineMeasureName": null,
        "calcMethodNameType": null,
        "firstWidth": 0.0,
        "secondWidth": 0.0
    },
    {
        "idStandard": 2,
        "idCountryStandard": 3,
        "idMeasureDiameterOption": 0,
        "description": null,
        "idMeasureDiameterMethod": 0,
        "idWalkingLineRadius": 0,
        "idCalcMethodType": 0,
        "idWalkingLineMeasure": 0,
        "standardName": "Francja NF E85-15 ewak.",
        "isActive": true,
        "freeHeadSpace": 2000.0,
        "isTlcStandard": false,
        "minLandingSize": 800.0,
        "minStepHeight": 160.0,
        "maxStepHeight": 200.0,
        "minConvinience": 660.0,
        "maxConvinience": 600.0,
        "maxStepDeep": 280.0,
        "minStepDeep": 180.0,
        "widthLimit": 900.0,
        "primaryCalcMethod": {
            "calcMethodName": "PrimaryCalcMethod",
            "walkingLineMeasure": 0,
            "calcMethod": 0,
            "firstWidth": 0.7,
            "secondWidth": 0.0,
            "idMeasureDiameterOption": 2,
            "description": "do 900mm szerokości biegu",
            "idMeasureDiameterMethod": 1,
            "idWalkingLineRadius": 3,
            "idCalcMethodType": 2,
            "idWalkingLineMeasure": 3
        },
        "secondaryCalcMethod": {
            "calcMethodName": "PrimaryCalcMethod",
            "walkingLineMeasure": 0,
            "calcMethod": 0,
            "firstWidth": 0.7,
            "secondWidth": 0.0,
            "idMeasureDiameterOption": 2,
            "description": "do 900mm szerokości biegu",
            "idMeasureDiameterMethod": 1,
            "idWalkingLineRadius": 3,
            "idCalcMethodType": 2,
            "idWalkingLineMeasure": 3
        },
        "maxStepWidth": 420.0,
        "startOverlap": 80.0,
        "endOverlap": 0.0,
        "walkLineOverlap": 0.0,
        "internalHandrailMaxRadius": 100.0,
        "maxStepsAmount": 0,
        "nameCountry": "Francja",
        "calcMethodName": null,
        "walkingLineMeasureName": null,
        "calcMethodNameType": null,
        "firstWidth": 0.0,
        "secondWidth": 0.0
    },
    {
        "idStandard": 2,
        "idCountryStandard": 3,
        "idMeasureDiameterOption": 0,
        "description": null,
        "idMeasureDiameterMethod": 0,
        "idWalkingLineRadius": 0,
        "idCalcMethodType": 0,
        "idWalkingLineMeasure": 0,
        "standardName": "Francja NF E85-15 ewak.",
        "isActive": true,
        "freeHeadSpace": 2000.0,
        "isTlcStandard": false,
        "minLandingSize": 800.0,
        "minStepHeight": 160.0,
        "maxStepHeight": 200.0,
        "minConvinience": 660.0,
        "maxConvinience": 600.0,
        "maxStepDeep": 280.0,
        "minStepDeep": 180.0,
        "widthLimit": 900.0,
        "primaryCalcMethod": {
            "calcMethodName": "SecondaryCalcMethod",
            "walkingLineMeasure": 0,
            "calcMethod": 0,
            "firstWidth": 600.0,
            "secondWidth": 0.0,
            "idMeasureDiameterOption": 3,
            "description": "powyżej 900mm",
            "idMeasureDiameterMethod": 2,
            "idWalkingLineRadius": 2,
            "idCalcMethodType": 1,
            "idWalkingLineMeasure": 3
        },
        "secondaryCalcMethod": {
            "calcMethodName": "SecondaryCalcMethod",
            "walkingLineMeasure": 0,
            "calcMethod": 0,
            "firstWidth": 600.0,
            "secondWidth": 0.0,
            "idMeasureDiameterOption": 3,
            "description": "powyżej 900mm",
            "idMeasureDiameterMethod": 2,
            "idWalkingLineRadius": 2,
            "idCalcMethodType": 1,
            "idWalkingLineMeasure": 3
        },
        "maxStepWidth": 420.0,
        "startOverlap": 80.0,
        "endOverlap": 0.0,
        "walkLineOverlap": 0.0,
        "internalHandrailMaxRadius": 100.0,
        "maxStepsAmount": 0,
        "nameCountry": "Francja",
        "calcMethodName": null,
        "walkingLineMeasureName": null,
        "calcMethodNameType": null,
        "firstWidth": 0.0,
        "secondWidth": 0.0
    },
    {
        "idStandard": 3,
        "idCountryStandard": 5,
        "idMeasureDiameterOption": 0,
        "description": null,
        "idMeasureDiameterMethod": 0,
        "idWalkingLineRadius": 0,
        "idCalcMethodType": 0,
        "idWalkingLineMeasure": 0,
        "standardName": "Norwegia TEK 17",
        "isActive": true,
        "freeHeadSpace": 2100.0,
        "isTlcStandard": true,
        "minLandingSize": 800.0,
        "minStepHeight": 160.0,
        "maxStepHeight": 210.0,
        "minConvinience": 590.0,
        "maxConvinience": 650.0,
        "maxStepDeep": 280.0,
        "minStepDeep": 160.0,
        "widthLimit": null,
        "primaryCalcMethod": {
            "calcMethodName": "PrimaryCalcMethod",
            "walkingLineMeasure": 0,
            "calcMethod": 0,
            "firstWidth": 400.0,
            "secondWidth": 0.0,
            "idMeasureDiameterOption": 4,
            "description": "400 mm od pochwytu",
            "idMeasureDiameterMethod": 1,
            "idWalkingLineRadius": 4,
            "idCalcMethodType": 1,
            "idWalkingLineMeasure": 1
        },
        "secondaryCalcMethod": null,
        "maxStepWidth": null,
        "startOverlap": 10.0,
        "endOverlap": 0.0,
        "walkLineOverlap": 0.0,
        "internalHandrailMaxRadius": null,
        "maxStepsAmount": 0,
        "nameCountry": "Norwegia",
        "calcMethodName": null,
        "walkingLineMeasureName": null,
        "calcMethodNameType": null,
        "firstWidth": 0.0,
        "secondWidth": 0.0
    }
]

下面是一个带绑定的模型

 public class Standard
    {
        [Key]
        public int IdStandard { get; set; }
        public string StandardName { get; set; }
        public bool IsActive { get; set; }
        public decimal FreeHeadSpace { get; set; }
        public decimal MinLandingSize { get; set; }
        public decimal MinStepHeight { get; set; }
        public decimal MaxStepHeight { get; set; }
        public decimal MinConvinience { get; set; }
        public decimal MaxConvinience { get; set; }
        public decimal? MaxStepDeep { get; set; }
        public decimal? MinStepDeep { get; set; }
        public decimal? WidthLimit { get; set; }
        public decimal? MaxStepWidth { get; set; }
        public decimal StartOverlap { get; set; }
        public decimal? EndOverlap { get; set; }
        public decimal? WalkLineOverlap { get; set; }
        public decimal? InternalHandrailMaxRadius { get; set; }
        public int? MaxStepsAmount { get; set; }
        public virtual ICollection<MeasureDiameterOption> MeasureDiameterOption { get; set; }
        public int IdCountryStandard { get; set; }
        public virtual CountryStandard CountryStandard { get; set; }
    }


 public class MeasureDiameterOption
    {
        [Key]
        public int IdMeasureDiameterOption { get; set; }
        public string Description { get; set; }
        [Display(Name = "Aktywna?")]
        public bool IsActive { get; set; }
        public int IdWalkingLineRadius { get; set; }
        public virtual WalkingLineRadius WalkingLineRadius { get; set; }
        public int? IdStandard { get; set; }
        public virtual Standard Standard { get; set; }
        public int IdMeasureDiameterMethod { get; set; }
        public virtual MeasureDiameterMethod MeasureDiameterMethod { get; set; }

    }

public class MeasureDiameterMethod
    {
        [Key]
        public int IdMeasureDiameterMethod { get; set; }
        public string CalcMethodName { get; set; }
        public virtual ICollection<MeasureDiameterOption> MeasureDiameterOption { get; set; }
    }

 public class WalkingLineRadius
    {
        [Key]
        public int IdWalkingLineRadius { get; set; }
        public decimal FirstWidth { get; set; }
        public decimal? SecondWidth { get; set; }   // 0.7
        public int IdWalkingLineMeasure { get; set; }
        public virtual WalkingLineMeasure WalkingLineMeasure { get; set; }
        public int IdCalcMethodType { get; set; }
        public virtual CalcMethodType CalcMethodType { get; set; }
        public virtual ICollection<MeasureDiameterOption> MeasureDiameterOption { get; set; }
   }

  public class CalcMethodType
    {      
        [Key]
        public int IdCalcMethodType { get; set; }
        public string CalcMethodNameType { get; set; }
        public virtual ICollection<WalkingLineRadius> WalkingLineRadius { get; set; }

    }


   public class WalkingLineMeasure
    {
        [Key]
        public int IdWalkingLineMeasure { get; set; }
        public string WalkingLineMeasureName { get; set; }
        public virtual ICollection<WalkingLineRadius> WalkingLineRadius { get; set; }
    }

我需要这个结果:

[
    {
        "idStandard": 1,
        "idCountryStandard": 2,
        "idMeasureDiameterOption": 0,
        "description": null,
        "idMeasureDiameterMethod": 0,
        "idWalkingLineRadius": 0,
        "idCalcMethodType": 0,
        "idWalkingLineMeasure": 0,
        "standardName": "Szwecja TLC Standard",
        "isActive": true,
        "freeHeadSpace": 2100.0,
        "isTlcStandard": true,
        "minLandingSize": 800.0,
        "minStepHeight": 160.0,
        "maxStepHeight": 240.0,
        "minConvinience": 590.0,
        "maxConvinience": 660.0,
        "maxStepDeep": null,
        "minStepDeep": null,
        "widthLimit": null,
        "primaryCalcMethod": {
            "calcMethodName": "PrimaryCalcMethod",
            "walkingLineMeasure": 0,
            "calcMethod": 0,
            "firstWidth": 300.0,
            "secondWidth": 0.0,
            "idMeasureDiameterOption": 1,
            "description": "od krawędzi zewnętrznej 300mm",
            "idMeasureDiameterMethod": 1,
            "idWalkingLineRadius": 1,
            "idCalcMethodType": 1,
            "idWalkingLineMeasure": 2
        },
        "secondaryCalcMethod": null,
        "maxStepWidth": null,
        "startOverlap": 10.0,
        "endOverlap": 0.0,
        "walkLineOverlap": 0.0,
        "internalHandrailMaxRadius": 131.0,
        "maxStepsAmount": 0,
        "nameCountry": "Szwecja",
        "calcMethodName": null,
        "walkingLineMeasureName": null,
        "calcMethodNameType": null,
        "firstWidth": 0.0,
        "secondWidth": 0.0
    },

    {
        "idStandard": 2,
        "idCountryStandard": 3,
        "idMeasureDiameterOption": 0,
        "description": null,
        "idMeasureDiameterMethod": 0,
        "idWalkingLineRadius": 0,
        "idCalcMethodType": 0,
        "idWalkingLineMeasure": 0,
        "standardName": "Francja NF E85-15 ewak.",
        "isActive": true,
        "freeHeadSpace": 2000.0,
        "isTlcStandard": false,
        "minLandingSize": 800.0,
        "minStepHeight": 160.0,
        "maxStepHeight": 200.0,
        "minConvinience": 660.0,
        "maxConvinience": 600.0,
        "maxStepDeep": 280.0,
        "minStepDeep": 180.0,
        "widthLimit": 900.0,
        "primaryCalcMethod": {
            "calcMethodName": "PrimaryCalcMethod",
            "walkingLineMeasure": 0,
            "calcMethod": 0,
            "firstWidth": 600.0,
            "secondWidth": 0.0,
            "idMeasureDiameterOption": 3,
            "description": "powyżej 900mm",
            "idMeasureDiameterMethod": 2,
            "idWalkingLineRadius": 2,
            "idCalcMethodType": 1,
            "idWalkingLineMeasure": 3
        },
        "secondaryCalcMethod": { "SecondaryCalcMethod",
            "calcMethodName": ,
            "walkingLineMeasure": 0,
            "calcMethod": 0,
            "firstWidth": 0.7,
            "secondWidth": 0.0,
            "idMeasureDiameterOption": 2,
            "description": "do 900mm szerokości biegu",
            "idMeasureDiameterMethod": 1,
            "idWalkingLineRadius": 3,
            "idCalcMethodType": 2,
            "idWalkingLineMeasure": 3
        },
        "maxStepWidth": 420.0,
        "startOverlap": 80.0,
        "endOverlap": 0.0,
        "walkLineOverlap": 0.0,
        "internalHandrailMaxRadius": 100.0,
        "maxStepsAmount": 0,
        "nameCountry": "Francja",
        "calcMethodName": null,
        "walkingLineMeasureName": null,
        "calcMethodNameType": null,
        "firstWidth": 0.0,
        "secondWidth": 0.0
    },
    {
        "idStandard": 3,
        "idCountryStandard": 5,
        "idMeasureDiameterOption": 0,
        "description": null,
        "idMeasureDiameterMethod": 0,
        "idWalkingLineRadius": 0,
        "idCalcMethodType": 0,
        "idWalkingLineMeasure": 0,
        "standardName": "Norwegia TEK 17",
        "isActive": true,
        "freeHeadSpace": 2100.0,
        "isTlcStandard": true,
        "minLandingSize": 800.0,
        "minStepHeight": 160.0,
        "maxStepHeight": 210.0,
        "minConvinience": 590.0,
        "maxConvinience": 650.0,
        "maxStepDeep": 280.0,
        "minStepDeep": 160.0,
        "widthLimit": null,
        "primaryCalcMethod": {
            "calcMethodName": "PrimaryCalcMethod",
            "walkingLineMeasure": 0,
            "calcMethod": 0,
            "firstWidth": 400.0,
            "secondWidth": 0.0,
            "idMeasureDiameterOption": 4,
            "description": "400 mm od pochwytu",
            "idMeasureDiameterMethod": 1,
            "idWalkingLineRadius": 4,
            "idCalcMethodType": 1,
            "idWalkingLineMeasure": 1
        },
        "secondaryCalcMethod": null,
        "maxStepWidth": null,
        "startOverlap": 10.0,
        "endOverlap": 0.0,
        "walkLineOverlap": 0.0,
        "internalHandrailMaxRadius": null,
        "maxStepsAmount": 0,
        "nameCountry": "Norwegia",
        "calcMethodName": null,
        "walkingLineMeasureName": null,
        "calcMethodNameType": null,
        "firstWidth": 0.0,
        "secondWidth": 0.0
    }
]

【问题讨论】:

标签: c# linq


【解决方案1】:

这是您需要的简化示例:

    class Program
    {
        static void Main(string[] args)
        {
            List<StandardEnt> ents = new List<StandardEnt>() {
                new StandardEnt() { IdStandard = 1},
                new StandardEnt() { IdStandard = 1},
                new StandardEnt() { IdStandard = 2},
                new StandardEnt() { IdStandard = 2},
                new StandardEnt() { IdStandard = 3},
                new StandardEnt() { IdStandard = 3},
                new StandardEnt() { IdStandard = 4},
                new StandardEnt() { IdStandard = 4},
                new StandardEnt() { IdStandard = 5},
                new StandardEnt() { IdStandard = 5},
                new StandardEnt() { IdStandard = 6},
                new StandardEnt() { IdStandard = 6}
            };

            List<StandardEnt> threeDistinct = ents.GroupBy(x => x.IdStandard).Select(x => x.FirstOrDefault()).Take(3).ToList();

 
        }
    }
    public class StandardEnt
    {
        public int IdStandard { get; set; }
    }

【讨论】:

  • 在记录 2 primaryCalcMethod 和 secondaryCalcMethod 我有相同的数据
  • 我使用 .GroupBy(x => x.IdStandard).Select(x => x.FirstOrDefault()).ToList();但在primaryCalcMethod 和secondaryCalcMethod 我有相同的数据
  • 那么你需要写一个 ICompare 来使用 Distinct。
  • 如何使用 ICompare Distinct 这是相当复杂的 linq 查询。
  • 这就是为什么我说要过滤第一个结果。请参阅:docs.microsoft.com/en-us/dotnet/api/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-09
  • 1970-01-01
  • 2021-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多