System.Linq.Dynamic.Core icon indicating copy to clipboard operation
System.Linq.Dynamic.Core copied to clipboard

How to generate a Select Expression with nested types?

Open maddemon opened this issue 1 year ago • 1 comments

I have two ViewModel types that are nested, and the Select statement I generate dynamically cannot correctly recognize the properties.

1. Description

My type definitions are as follows:

    [Table("project_sample")]
    public class ProjectSample : FormData
    {
        [Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
        [ForeignKey("Project")]
        public override string Id { get; set; } = string.Empty;
        [JsonIgnore]
        public virtual Project? Project { get; set; }
        public int? Result { get; set; }
        public string? Opinion { get; set; }
        [JsonIgnore]
        public virtual List<ProjectSampleExpertPoint>? ExpertPoints { get; set; }
    }

    [Table("project_smaple_expert_point")]
    public class ProjectSampleExpertPoint : FormData
    {
        public string? BatchId { get; set; }
        public string? ProjectSampleId { get; set; }
        [JsonIgnore]
        public virtual ProjectSample? ProjectSample { get; set; }
        public string? ExpertId { get; set; }
        [JsonIgnore]
        public virtual User? Expert { get; set; }
        public string? Opinion { get; set; }
        public int? Result { get; set; }
        [JsonIgnore]
        [Column("Attachment", TypeName = "JSON")]
        public string? AttachmentValue { get; set; }
        [NotMapped]
        public UploadFile? Attachment
        {
            get => AttachmentValue?.ToObject<UploadFile>();
            set => AttachmentValue = value?.ToJson();
        }
    }

    public class VProjectSample : ProjectSample
    {
        [Relation("Project.BatchId")]
        public string? BatchId { get; set; }
        [Relation("Project")]
        public new Project? Project { get; set; }
        [Relation("Project.Organization.FullName")]
        public string? OrganizationName { get; set; }
        [Relation("Project.Organization.Tel")]
        public string? OrganizationTel { get; set; }
    }

    public class VProjectSamplePoint : VProjectSample
    {
        [Relation("ExpertPoints")]
        public List<VProjectSampleExpertPoint>? Experts { get; set; }
    }

    public class VProjectSampleExpertPoint : ProjectSampleExpertPoint
    {
        [Relation("Expert.Name")]
        public string? ExpertName { get; set; }
    }

The Select string I generated is as follows:

	new {
		ExpertPoints.Select(new {
			Expert.Name AS ExpertName,
			BatchId,
			ProjectSampleId,
			ExpertId,
			Opinion,
			Result,
			AttachmentValue,
			CreateTime,
			UpdateTime,
			Deleted,
			Id
		}) AS Experts,
		
		Project.BatchId AS BatchId,
		Project AS Project,
		Project.Organization.FullName AS OrganizationName,
		Project.Organization.Tel AS OrganizationTel,
		Id,
		Result,
		Opinion,
		CreateTime,
		UpdateTime,
		Deleted
	}

My code:

  DynamicExpressionParser.ParseLambda<ProjectSample, VProjectSamplePoint>(new ParsingConfig { ResolveTypesBySimpleName = true,}, true, selectExp);

2. Exception

Exception message:No property or field 'ExpertName' exists in type 'VProjectSamplePoint'
Stack trace:at System.Linq.Dynamic.Core.Parser.ExpressionParser.CreateNewExpression(List`1 properties, List`1 expressions, Type newType) in D:\\repos\\System.Linq.Dynamic.Core-1.4.4\\src\\System.Linq.Dynamic.Core\\Parser\\ExpressionParser.cs:line 1599\r\n   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseNew() in D:\\repos\\System.Linq.Dynamic.Core-1.4.4\\src\\System.Linq.Dynamic.Core\\Parser\\ExpressionParser.cs:line 1476\r\n   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseIdentifier() in D:\\repos\\System.Linq.Dynamic.Core-1.4.4\\src\\System.Linq.Dynamic.Core\\Parser\\ExpressionParser.cs:line 1016\r\n   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParsePrimaryStart() in D:\\repos\\System.Linq.Dynamic.Core-1.4.4\\src\\System.Linq.Dynamic.Core\\Parser\\ExpressionParser.cs:line 838\r\n   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParsePrimary() in D:\\repos\\System.Linq.Dynamic.Core-1.4.4\\src\\System.Linq.Dynamic.Core\\Parser\\ExpressionParser.cs:line 806\r\n   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseUnary() in D:\\repos\\System.Linq.Dynamic.Core-1.4.4\\src\\System.Linq.Dynamic.Core\\Parser\\ExpressionParser.cs:line 801\r\n   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseArithmetic() in D:\\repos\\System.Linq.Dynamic.Core-1.4.4\\src\\System.Linq.Dynamic.Core\\Parser\\ExpressionParser.cs:line 746\r\n   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseAdditive() in D:\\repos\\System.Linq.Dynamic.Core-1.4.4\\src\\System.Linq.Dynamic.Core\\Parser\\ExpressionParser.cs:line 713\r\n   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseShiftOperator() in D:\\repos\\System.Linq.Dynamic.Core-1.4.4\\src\\System.Linq.Dynamic.Core\\Parser\\ExpressionParser.cs:line 689\r\n   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseComparisonOperator() in D:\\repos\\System.Linq.Dynamic.Core-1.4.4\\src\\System.Linq.Dynamic.Core\\Parser\\ExpressionParser.cs:line 479\r\n   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseLogicalAndOrOperator() in D:\\repos\\System.Linq.Dynamic.Core-1.4.4\\src\\System.Linq.Dynamic.Core\\Parser\\ExpressionParser.cs:line 411\r\n   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseIn() in D:\\repos\\System.Linq.Dynamic.Core-1.4.4\\src\\System.Linq.Dynamic.Core\\Parser\\ExpressionParser.cs:line 330\r\n   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseAndOperator() in D:\\repos\\System.Linq.Dynamic.Core-1.4.4\\src\\System.Linq.Dynamic.Core\\Parser\\ExpressionParser.cs:line 313\r\n   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseOrOperator() in D:\\repos\\System.Linq.Dynamic.Core-1.4.4\\src\\System.Linq.Dynamic.Core\\Parser\\ExpressionParser.cs:line 295\r\n   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseLambdaOperator() in D:\\repos\\System.Linq.Dynamic.Core-1.4.4\\src\\System.Linq.Dynamic.Core\\Parser\\ExpressionParser.cs:line 273\r\n   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseNullCoalescingOperator() in D:\\repos\\System.Linq.Dynamic.Core-1.4.4\\src\\System.Linq.Dynamic.Core\\Parser\\ExpressionParser.cs:line 260\r\n   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseConditionalOperator() in D:\\repos\\System.Linq.Dynamic.Core-1.4.4\\src\\System.Linq.Dynamic.Core\\Parser\\ExpressionParser.cs:line 244\r\n   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseOutKeyword() in D:\\repos\\System.Linq.Dynamic.Core-1.4.4\\src\\System.Linq.Dynamic.Core\\Parser\\ExpressionParser.cs:line 196\r\n   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseArguments() in D:\\repos\\System.Linq.Dynamic.Core-1.4.4\\src\\System.Linq.Dynamic.Core\\Parser\\ExpressionParser.cs:line 2257\r\n   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseArgumentList() in D:\\repos\\System.Linq.Dynamic.Core-1.4.4\\src\\System.Linq.Dynamic.Core\\Parser\\ExpressionParser.cs:line 2243\r\n   at System.Linq.Dynamic.Core.Parser.ExpressionParser.TryParseEnumerable(Expression instance, Type elementType, String methodName, Int32 errorPos, Type type, Expression[]& args, Expression& expression) 

3. Any further technical details

In my code, the nested Select ' AS Experts' should be the type 'VProjectSampleExpertPoint', but it does not automatically convert. How should I generate the correctly selectExp?

maddemon avatar Aug 16 '24 08:08 maddemon

@maddemon

  • can you please provide a full working example (without the attributes)
  • also instead of using DynamicExpressionParser.ParseLambda, use a normal select and

StefH avatar Oct 13 '24 12:10 StefH