我正在使用新的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)的几件事情,但没有发现任何对我有用的东西。
我不太确定这是否可行,但我们将不胜感激。
答案 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。