Search code examples
c#linqdynamictype

How to get dynamic type property?


I have a project that I should place some code in other layer and because of this I should transfer a linq query to method. This code:

var HRPersonnelContactInfoTelService = App.Api.HRPersonnelContactInfoTelService.Instance().Data();
        var SMSGroupMemberService = App.Api.SMSGroupMemberService.Instance().Data();
        return (from x in SMSGroupMemberService
                where Recivers.Contains(x.GroupID)
                join v in HRPersonnelContactInfoTelService on x.Pers_Code equals v.Pers_Code
                select new { Pers_Code = (int)x.Pers_Code, Tel = v.Tel }).ToList();

I converted up code to:

public dynamic HRPersonnelContactInfoTelMethod(List<int> Recivers)
    {
        var HRPersonnelContactInfoTelService = App.Api.HRPersonnelContactInfoTelService.Instance().Data();
        var SMSGroupMemberService = App.Api.SMSGroupMemberService.Instance().Data();
        return (from x in SMSGroupMemberService
                where Recivers.Contains(x.GroupID)
                join v in HRPersonnelContactInfoTelService on x.Pers_Code equals v.Pers_Code
                select new { Pers_Code = (int)x.Pers_Code, Tel = v.Tel }).ToList();
    }

but when I use it in foreach

An exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred in System.Core.dll but was not handled in user code

Additional information: 'object' does not contain a definition for 'Pers_Code'

Use it like this:

var q = App.Api.HRPersonnelContactInfoTelService.Instance().HRPersonnelContactInfoTelMethod(Recivers);
        foreach (var item in Recivers)
        {
            var res = App.Api.SMSMessageGroupService.Instance().AddOrUpdate(null, MessageId, item);
        }
        foreach (var z in q)
        {
            string SendNumber = Number[1].Trim().Substring(0, 3) == "+98" ? Number[1].Trim() : "+98" + Number[1].Trim();
            var res = App.Api.SMSMessageLogService.Instance().AddOrUpdate(null, MessageId, (int)z.Pers_Code, z.Tel.ToString(),
                 0, int.Parse(ddlSMSWorkingGroups.SelectedValue.ToString()), (int)z.Pers_Code, SendNumber, 0);
            send.SendSMS("nazmaran", "qwerty", SendNumber, "09122596898", txtPredefinedRemarks.Text);
        }

Solution

  • I would never use dynamic to return the result of a linq query that uses anonymous types to project the results. Instead, I would create a class that holds the results:

    public class SomeName
    {
       public int Pers_Code { set; get; }
       public string /* Change to Correct Type */ Tel { set; get;}
    }
    

    Usage:

    public List<SomeName> HRPersonnelContactInfoTelMethod(List<int> Recivers)
    {
       var HRPersonnelContactInfoTelService = App.Api.HRPersonnelContactInfoTelService.Instance().Data();
       var SMSGroupMemberService = App.Api.SMSGroupMemberService.Instance().Data();
       return (from x in SMSGroupMemberService
               where Recivers.Contains(x.GroupID)
               join v in HRPersonnelContactInfoTelService on x.Pers_Code equals v.Pers_Code
               select new SomeName() { Pers_Code = (int)x.Pers_Code, Tel = v.Tel }).ToList();
    }
    

    Creating a type to hold the results is nothing compared to the complexity of used dynamic.