加入Linq表达式

时间:2010-07-20 01:35:56

标签: linq entity-framework

我正在使用新的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
}

结果我需要是一个表达式< Func< T,object>>。我一直在四处寻找使用Expression.Invoke和Expression.And(andalso)的几件事情,但没有发现任何对我有用的东西。

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

1 个答案:

答案 0 :(得分: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。