【问题标题】:Joining Linq Expressions加入 Linq 表达式
【发布时间】:2010-07-20 21:01:00
【问题描述】:

我正在使用新的 EF4 CTP4,尽管我认为这与此没有太大关系。我正在尝试建立一个可以自动为我们的数据库添加可审计字段的系统。我正在尝试做的是结合以下两个表达式

a => new
{
    a.CreatedBy,
    a.CreatedTime,
    a.UpdatedBy,
    a.UpdatedTime
}

a => new
{
    a.Id,
    a.Name,


}

所以结果等价于

a => new
{
    a.Id,
    a.Name,
    a.CreatedBy,
    a.CreatedTime,
    a.UpdatedBy,
    a.UpdatedTime
}

我需要的结果是一个表达式>。我一直在四处寻找并尝试了 Expression.Invoke 和 Expression.And(andalso) 的一些事情,但没有找到任何对我有用的东西。

我不太确定这是否可行,但我们将不胜感激。

【问题讨论】:

  • EF4 已作为 .NET 4.0 的一部分正式发布。
  • 我指的是 ADO.Net Feature CTP4,它允许代码优先/仅代码 ef 开发
  • 您想要一个具有以下签名的方法,对吗? Expression<Func<T,AuditObject>> ProjectToAuditObject<T>() where T: IAuditable 其中AuditObject 包含必需的属性(IdName 等)。
  • 不完全是,我的 T 对象已经具有上面显示的所有属性,对象需要是匿名类型。我正在尝试轻松地将映射添加到我的可审计字段的数据库中。如果您已播种 ef4 ctp。这是我试图调用的实际代码
  • MapSingleType(AuditablePropertyMap.Map(a => new { a.Id, a.Name })).ToTable("dbo.Teams");其中 auditablePropertyMap 看起来像这样 public static Expression> Map(Expression> propertyMap) where T : IAuditable { Expression> expr = (a => 新 { a.CreatedBy, a.CreatedTime, a.UpdatedBy, a.UpdatedTime }); //这里要做什么来合并两个表达式的成员

标签: linq entity-framework


【解决方案1】:

我认为你不能简单地“合并”两个表达式。但是您可以使用备用 API 创建与 EntityMap 的映射。

public static class MapBuilder
{
    public static Expression<Func<T, object>> GetMap<T>(Expression<Func<T, object>> func) where T: IAuditable
    {
        var body = func.Body as NewExpression;

        var param = Expression.Parameter(typeof(T), "o");

        var propertyAccessExprs = new List<Expression>();

        foreach (MemberInfo member in body.Members)
        {
            propertyAccessExprs.Add(Expression.Property(param, member.Name));
        }

        var props = typeof(IAuditable).GetProperties();

        foreach (PropertyInfo prop in props)
        {
            propertyAccessExprs.Add(Expression.Property(param, prop.Name));
        }

        var columnMappins = new List<Expression>();

        foreach (var access in propertyAccessExprs)
        {
            columnMappins.Add(Expression.Call(typeof(EntityMap).GetMethod("Column", new Type[] {typeof(Object)}), Expression.Convert(access, typeof(Object))));
        }

        var RowExpr = Expression.Call(typeof(EntityMap).GetMethod("Row"), Expression.NewArrayInit(typeof(EntityMapColumn), columnMappins));

        var result = Expression.Lambda<Func<T, object>>(RowExpr, param);

        return result;
    }
}

用法是

 var builder = new ModelBuilder();
            builder.Entity<SimpleAuditableObject>()
                .HasKey(o => o.Id)
                .MapSingleType(MapBuilder.GetMap<SimpleAuditableObject>(o => new { o.Id, o.Name }));

在哪里

public interface IAuditable
{
    int CreatedBy { get; set; }
    DateTime CreatedTime { get; set; }
    int UpdatedBy { get; set; }
    DateTime UpdatedTime { get; set; }
}

public class SimpleAuditableObject : IAuditable
{
    public int Id { get; set; }
    public string Name { get; set; }

    public int CreatedBy { get; set; }
    public DateTime CreatedTime { get; set; }
    public int UpdatedBy { get; set; }
    public DateTime UpdatedTime { get; set; }
}

HTH。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-01
    • 2015-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多