简体   繁体   中英

'Expression of type 'System.String' cannot be used for parameter of type 'System.Reflection.PropertyInfo'

I have two classes - ContactCompany and inside List of ContactPeople.

The result must be - list of all contact people or a specific contact person that matches a certain criteria.

The criteria is a string and it will search all the string fields in both classes. If a ContactCompany is found, all the list of contact people will be displayed.

So Far I came up with this:

public List<ContactPersonDto> FilterContragentAndClients(string filter)
{
    var contactCompanyStringProperties = typeof(ContactCompany).GetProperties().Where(prop => prop.PropertyType == filter.GetType() && prop.DeclaringType.Name != "AuditEntity`1");
    var contactPersonStringProperties = typeof(ContactPerson).GetProperties().Where(prop => prop.PropertyType == filter.GetType());
    var together = contactCompanyStringProperties.Concat(contactPersonStringProperties);

    var allContactPersonFoundInCompany = this.contactCompanyRepository.GetAll(cc => contactCompanyStringProperties.Any
        (prop => ((prop.GetValue(cc, null) == null) ? "" : prop.GetValue(cc, null).ToString().ToLower()) == filter)).SelectMany(acc => acc.ContactPeople).ToList();

    var contactPersonOnItsOwn = contactPersonRepository.GetAll(cp => contactPersonStringProperties.Any
        (prop => ((prop.GetValue(cp, null) == null) ? "" : prop.GetValue(cp, null).ToString().ToLower()) == filter));

    var totalList = allContactPersonFoundInCompany.Concat(contactPersonOnItsOwn).Distinct().ToList().Take(100);

    List<ContactPersonDto> result = new List<ContactPersonDto>();
    foreach (var item in totalList)
    {
        result.Add(mapper.Map<ContactPersonDto>(item));
    }
    return result;
}

My idea was to check the property and its value, ToString() it and compare it with the criteria the user has inputted.

Just another note - I wrote the prop.Declarintype.Name in order to exclude AuditEntity properties.(Created By, Created At, etc.)

When I hit allContactPersonFoundInCompany the ToString() cannot be translated.

This is the full error I receive:

Expression of type 'System.String' cannot be used for parameter of type 'System.Reflection.PropertyInfo' of method 'Boolean Contains[PropertyInfo](System.Collections.Generic.IEnumerable`1[System.Reflection.PropertyInfo], System.Reflection.PropertyInfo)' (Parameter 'arg1')

I understood the implications of reflection, it is very slow, therefore here is my solution.

 public List<ContactPersonDto> FilterContragentAndClients(string filter)
        {
            var contactPeopleInCompany = this.contactCompanyRepository.GetAll
                (c => c.AccountablePerson.Contains(filter) |
                 c.Address.Contains(filter) ||
                 c.City.Contains(filter) ||
                 c.Name.Contains(filter) ||
                 c.Prefix.Contains(filter) ||
                 c.RegistrationNumber.Contains(filter)).SelectMany(c => c.ContactPeople);

            var contactPerson = this.contactPersonRepository.GetAll
                (cp => cp.Address.Contains(filter) ||
                cp.Email.Contains(filter) ||
                cp.Name.Contains(filter) ||
                cp.PhoneNumber.Contains(filter) ||
                cp.Prefix.Contains(filter));

            var together = contactPeopleInCompany.Concat(contactPerson).Distinct().Take(100).ToList();

            List<ContactPersonDto> result = new List<ContactPersonDto>();
            foreach (var item in together)
            {
                result.Add(mapper.Map<ContactPersonDto>(item));
            }
            return result;
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM