我在UnitOfWork和EntityFramework中遇到了一些问题。
这是我的UnitOfWork界面。
public interface IUnitOfWork
{
IRepository<CarPOCO> Cars { get; }
void SaveChanges();
}
CarPOCO是一个简单的实体模型。
public class CarPOCO
{
public virtual int Id { get; set; }
}
IUnitOfWork实现之一将使用内部EntityFramework上下文和自定义(也是内部)模型类。
internal class CarEFModel
{
public virtual int Id { get; set; }
}
我还创建了一个CarPOCOProxy,将其与EF存储库一起使用。
public class CarPOCOProxy : CarPOCO
{
private CarEFModel wrappedModel;
public CarEFModel WrappedModel
{
get
{
return this.wrappedModel;
}
}
public CarPOCOProxy()
: this(new CarEFModel())
{
}
public CarPOCOProxy(CarEFModel efmodel)
{
this.wrappedModel = efmodel;
}
public override int Id
{
get
{
return wrappedModel.Id;
}
set
{
wrappedModel.Id = value;
}
}
}
这是EF Cars存储库:
private class CarsRepository : IRepository<CarPOCO>
{
private MyDbContext context;
public CarsRepository(MyDbContext context)
{
this.context = context;
}
public void Insert(CarPOCO entity)
{
var casted = this.MyCast(entity);
this.context.EFCars.Add(casted.WrappedModel);
}
public void Update(CarPOCO entity)
{
...
}
public void Delete(CarPOCO entity)
{
var casted = this.MyCast(entity);
this.context.EFCars.Remove(casted.WrappedModel);
}
public CarPOCO CreateNew()
{
return new CarPOCOProxy();
}
private CarPOCOProxy MyCast(CarPOCO car)
{
return (CarPOCOProxy)car;
}
public IList<CarPOCO> Select(Expression<Func<CarPOCO, bool>> predicate)
{
Func<CarPOCO, bool> func = predicate.Compile();
Expression<Func<CarEFModel, bool>> castedPredicate = g => func(new CarPOCOProxy(g));
var queryable = this.context.EFCars.Where(castedPredicate);
return queryable.ToList().Select(g => new CarPOCOProxy(g)).Cast<CarPOCO>().ToList();
}
}
插入,删除和更新工作正常,但绝对不按谓词选择。 EF无法从我的castedPredicate构建SQL查询:
Expression<Func<CarEFModel, bool>> castedPredicate = g => func(new CarPOCOProxy(g));
// The LINQ expression node type 'Invoke' is not supported in LINQ to Entities.
这是测试程序:
class Program
{
static void Main(string[] args)
{
IUnitOfWork unit = new EFUnitOfWork();
CarPOCO newCar = unit.Cars.CreateNew();
unit.Cars.Insert(newCar);
unit.SaveChanges();
var found = unit.Cars.Select(g => g.Id == 0).FirstOrDefault();
}
}
是否有可能从
施放Expression<Func<CarPOCO, bool>>
到
Expression<Func<CarEFModel, bool>>
在我将它传递给DbContext之前?
[编辑] 我的解决方案之一是不在存储库级别使用基于表达式的方法,而是使用特定的简单类型查询方法(如下所示)。无论如何,我仍然很好奇如何用表达式做到这一点。
public CarPOCO GetById(int id)
{
var found = this.context.EFCars.FirstOrDefault(g => g.Id == id);
if (found != null)
{
return new CarPOCOProxy(found);
}
else
{
return null;
}
}