在我的通用存储库中,我需要编写通用的Save方法,该方法将根据id编辑已存在或添加新实体。
public void Save<T>(T entity) where T : TEntity, IKeyId
{
if (ObjectSet.Any(r => (r as IKeyId).KeyId == entity.KeyId))
{
Edit(entity);
}
else
{
Add(entity);
}
}
但是当我尝试Any( r=> (r as IKeyId)...
时,Linq会产生异常。
不支持带有“MyProg.DAL.Appeal”类型输入的“TypeAs”表达式和“Claimstrak.DAL.Interfaces.IKeyId”类型的检查。 LINQ to Entities查询仅支持实体类型和复杂类型。
如何写得正确?
答案 0 :(得分:1)
嗯,事实是你不需要使用ObjectSet,你可以用更简单的方式使用DbContext来做到这一点。
Bu,我会说这不是一个好的模式,可以在存储库中调用Save()。我建议你在完成所有操作之后才考虑上下文的.SaveSession(),这样你就可以做很多事情来完成数据库的往返。
所以,你应该创建一个像这样的方法,但是不要将SaveChanges()而不是Save()方法调用到UpdateOrInsert()和它们,在完成所有操作之后你调用.Save()
但我会根据您的要求提供示例(但我不建议,我建议您将IUnitOfWork与IRepository分开)
看看代码是如何简单的:
interface IKeyId
{
int Id { get; set; }
}
DbContext context = new YourContext();
public bool Save<TEntity>(TEntity entity) where TEntity : class, IKeyId
{
return (entity.Id == 0) ? Add<TEntity>(entity) : Edit<TEntity>(entity);
}
public bool Edit<TEntity>(TEntity entity) where TEntity : class, IKeyId
{
var set = context.Set<TEntity>();
set.Attach(entity);
return true;
}
public bool Add<TEntity>(TEntity entity) where TEntity : class, IKeyId
{
var set = context.Set<TEntity>();
set.Add(entity);
return true;
}
我在我的存储库中使用类似的方法,我已经更改了从我的数据库生成POCO类的T4(.tt文件),以明确地实现我拥有的一些接口,例如IAuditable,IValidatable等,所以T4自动实现类中的那些接口。