Salman
Salman

Reputation: 1286

Convert Expression<Func<DTOUser, bool>> predicate to Expression<Func<User, bool>> predicate

I have a problem in Expression

I have an Entity

public class User{ 
public string Username{get;set;}
  public int PhoneNumber{get;set;}
  public string FIrstName{get;set;}
  public string LastName{get;set;}
}

and I have a DTO

public class DTOUser{
  public string Username{get;set;}
  public int PhoneNumber{get;set;}
  public string FIrstName{get;set;}
  public string LastName{get;set;}
  }

Then I have a snippet code generic

 public IList<DTOUser> SelectAll(Expression<Func<DTOUser, bool>> predicate)
    {
           using (var adc = _conn.GetContext())
        {   
       // what should I do ?? so i can convert Predciate to get all values from Users (Entity)   
//it generates an error because predicate can't be cast into Entity User                    
 //   var users = adc.Users.All(predicate);
       }          
    }

I wanted to get a list of DTOUser by Passing LAMBDA Expression

accountrepo.SelectAll( user => user.firstname.equals ("sample"));

I have researched this issue and come to the conclusion that because DTOUser and User are of different type, it's difficult to cast the Expression from one type to another.

One solution has been suggested by Jon Skeet:

How to cast Expression<Func<T, DateTime>> to Expression<Func<T, object>>

but as this solution seems that I have to map each value from DTOUser to User doesn't this make it more complex as my DTOUser contains more than 15 properties.

Can someone help me out?

Upvotes: 4

Views: 1706

Answers (2)

AlexH
AlexH

Reputation: 2700

You cannot cast directly from one type to another, you can do:

  1. a manual mapping
  2. map automatically using reflection (as propery names are the same)
  3. Use AutoMapper

For mapping using reflection, you can use the following generic code :

public static T1 CopyProperties<T1, T2>(T2 model)
    where T1 : new()
    where T2 : new()
{
    // Get all the properties in the model
    var type = model.GetType();
    var properties = type.GetProperties();

    var result = new T1();
    var resultType = result.GetType();
    var resultProperties = resultType.GetProperties();

    // Loop through each property
    foreach (var property in properties)
    {
        var resultProperty = resultProperties.FirstOrDefault(n => n.Name == property.Name && n.PropertyType == property.PropertyType);
        if (resultProperty != null)
        {
            resultProperty.SetValue(result, property.GetValue(model, null), null);
        }
    }
    return result;
}

It will copy properties with the same types and names

Upvotes: 2

Honza Brestan
Honza Brestan

Reputation: 10957

I think you can use Jon Skeet's answer from your link, and define an explicit cast from DTOUser to User in your User (partial) class:

public static explicit operator User(DTOUser dto)
{
    return new User
    {
        Prop1 = dto.Prop1,
        Prop2 = dto.Prop2,
        ...
    }
}

Upvotes: 0

Related Questions