【问题标题】:Convert Expression<Func<DTOUser, bool>> predicate to Expression<Func<User, bool>> predicate将 Expression<Func<DTOUser, bool>> 谓词转换为 Expression<Func<User, bool>> 谓词
【发布时间】:2012-11-29 12:12:12
【问题描述】:

我的表达式有问题

我有一个实体

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

我有一个 DTO

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

然后我有一个sn-p代码通用

 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);
       }          
    }

我想通过传递 LAMBDA 表达式获取 DTOUser 列表

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

我研究过这个问题并得出结论,因为 DTOUser 和 User 是不同的类型,所以很难将 Expression 从一种类型转换为另一种类型。

Jon Skeet 提出了一种解决方案:

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

但由于这个解决方案似乎我必须将每个值从 DTOUser 映射到 User,这不会使它变得更复杂,因为我的 DTOUser 包含超过 15 个属性。

有人可以帮帮我吗?

【问题讨论】:

  • @user751959 据我了解您的问题,您希望在 User 类型的对象上应用期望类型 DTOUser 的表达式。您能否编辑问题,使其更清楚?
  • 不知道如何删除我的重复标志,我只是读得太快了。我很抱歉。
  • @MiroslavBajtoš 我想要的是将 Expression> 转换为 Expression> 以便 adc.Users.All(predicate );

标签: c# expression predicate


【解决方案1】:

您不能直接从一种类型转换为另一种类型,您可以这样做:

  1. 手动映射
  2. 使用反射自动映射(因为属性名称相同)
  3. 使用AutoMapper

对于使用反射的映射,您可以使用以下通用代码:

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;
}

它将复制具有相同类型和名称的属性

【讨论】:

  • 旧解决方案中有 24 个表。如果我开始编写手动映射,则代码维护将花费大量时间和成本。如果您可以用一个小代码示例详细说明第二种方法,即自动使用反射,请说明。
  • AutoMapper 应该是一个很好的解决方案,因为类具有相同的属性名称
  • 感谢您帮助我,真的感谢我更喜欢使用 Automapper。
【解决方案2】:

我认为您可以从链接中使用 Jon Skeet 的答案,并在您的 User(部分)类中定义从 DTOUser 到 User 的显式转换:

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

【讨论】:

    猜你喜欢
    • 2021-06-17
    • 2021-08-25
    • 2013-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-02
    • 1970-01-01
    • 2010-10-25
    相关资源
    最近更新 更多