Cos*_*nea 6 entity-framework code-first entity-framework-4 ef-code-first entity-framework-ctp5
我在MSDN上关注这篇文章.我把它移植到EF Code First.
public interface IUnitOfWork
{
IRepository<Employee> Employees { get; }
IRepository<TimeCard> TimeCards { get; }
void Commit();
}
Run Code Online (Sandbox Code Playgroud)
public class HrContext : DbContext
{
public DbSet<Employee> Employees { get; set; }
public DbSet<TimeCard> TimeCards { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Employee>()
.HasMany(e => e.TimeCards)
.WithOptional(tc => tc.Employee);
}
}
Run Code Online (Sandbox Code Playgroud)
public class SqlRepository<T> : IRepository<T>
where T : class
{
private readonly DbSet<T> entitySet;
public SqlRepository(DbContext context)
{
this.entitySet = context.Set<T>();
}
public void Add(T newEntity)
{
this.entitySet.Add(newEntity);
}
public IQueryable<T> FindAll()
{
return this.entitySet;
}
public T FindById(params object[] keys)
{
return this.entitySet.Find(keys);
}
public IQueryable<T> FindWhere(Expression<Func<T, bool>> predicate)
{
return this.entitySet.Where(predicate);
}
public void Remove(T entity)
{
this.entitySet.Remove(entity);
}
}
Run Code Online (Sandbox Code Playgroud)
public class SqlUnitOfWork : IUnitOfWork, IDisposable
{
private readonly HrContext context;
private IRepository<Employee> employees;
private IRepository<TimeCard> timeCards;
public SqlUnitOfWork()
{
this.context = new HrContext();
}
public IRepository<Employee> Employees
{
get
{
return new SqlRepository<Employee>(context);
}
}
public IRepository<TimeCard> TimeCards
{
get
{
return new SqlRepository<TimeCard>(context);
}
}
public void Commit()
{
this.context.SaveChanges();
}
public void Dispose()
{
context.Dispose();
}
}
Run Code Online (Sandbox Code Playgroud)
var query = from e in unitOfWork.Employees.FindAll()
from tc in unitOfWork.TimeCards.FindAll()
where tc.Employee.Id == e.Id && e.Name.StartsWith("C")
select tc;
var timeCards = query.ToList();
Run Code Online (Sandbox Code Playgroud)
这个模型很棒,因为它给我可测试性.但是,像上面那样运行查询会引发这种情况
LINQ to Entities does not recognize the method
'System.Linq.IQueryable`1[DomainModel.Models.TimeCard] FindAll()'
method, and this method cannot be translated into a store expression.
Run Code Online (Sandbox Code Playgroud)
我理解错误,但是有什么办法可以避免它,但仍然保留了可测试性的存储库?
由于IQueryable<T>查询提供者的工作方式和性质,您的select语句无法翻译:有关更多信息,请参见此线程。IQueryable <T>和IEnumerable <T>有什么区别?
您可以通过将表达式分成以下单独的语句来“帮助” linq提供程序:
var ems = unitOfWork.Employees.FindAll();
var tcs = unitOfWork.TimeCards.FindAll();
var query = from e in ems
from tc in tcs
where tc.Employee.Id == e.Id && e.Name.StartsWith("C")
select tc;
Run Code Online (Sandbox Code Playgroud)
或者,您可以让FindAll()返回IEnumerable<T>而不是,IQueryable<T>然后您的原始表达式应该起作用。
| 归档时间: |
|
| 查看次数: |
2926 次 |
| 最近记录: |