LINQ to Entities不识别方法 [英] LINQ to Entities does not recognize the method
问题描述
我正在MSDN上关注这篇文章。我将其移植到EF Code First。
I am following this article on MSDN. I ported it to EF Code First.
public interface IUnitOfWork
{
IRepository<Employee> Employees { get; }
IRepository<TimeCard> TimeCards { get; }
void Commit();
}
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);
}
}
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);
}
}
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();
}
}
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();
这个模型是伟大的,因为它给了我可测试性。但是,像上面那样运行的查询会抛出这个错误。
This model is great as it gives me testability. However, running queries like the one above throws this
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.
我明白了错误,但是有什么办法可以避免这种错误,但仍然保留这些存储库的可测试性? / p>
I understand the error but is there any way to avoid it but still keep the repositories for testability?
推荐答案
由于 IQueryable< T> $ c的性质,您的select语句无法翻译$ c>和查询提供者工作:查看此主题了解更多信息什么是IQueryable< T>之间的区别。和IEnumerable< T>?
Your select statement cannot be translated due to the nature of how IQueryable<T>
and the query providers work: see this thread for more info What is the difference between IQueryable<T> and IEnumerable<T>?
您可以通过将表达式分成单独的语句来帮助linq提供者:
You can 'help' the linq provider by dividing your expression into separate statements like this:
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;
或者您可以让FindAll()返回 IEnumerable< T>
而不是 IQueryable< T>
然后你的原始表达式应该工作。
Or you can let FindAll() return IEnumerable<T>
instead of IQueryable<T>
and then your original expression should work.
这篇关于LINQ to Entities不识别方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!