我试图想出一种方法将一组include语句传递到我的存储库中,这样我就可以让它包含特定的实体。以下是我的存储库中的一些示例代码。
public TEntity GetById(Guid id)
{
return id != Guid.Empty ? GetSet().Find(id) : null;
}
private IDbSet<TEntity> GetSet()
{
return _unitOfWork.CreateSet<TEntity>();
}
GetByID方法调用GetSet以返回实体集。我在想,如果我能以某种方式传入一个实体集合(通过表达式)作为我的GetById的一部分,这样我就不必将GetSet公开给我的服务了。所以,像这样:
var entity = _repository.GetById(theId,e =&gt; {e.Prop1,e.Prop2,e.Prop3});
然后我可以将该表达式传递给我的GetSet方法并将其传递给include语句。想法?
答案 0 :(得分:16)
我最近在我的代码中做过类似的事情。以下是否适合您?
public TEntity GetById(Guid id, params Expression<Func<TEntity, object>>[] includeProperties)
{
if (id == Guid.Empty) return null;
var set = _unitOfWork.CreateSet<TEntity>();
foreach(var includeProperty in includeProperties)
{
set.Include(includeProperty);
}
return set.First(i => i.Id == id);
}
然后你会这样称呼它......
var entity = _repository.GetById(theId, e => e.Prop1, e=> e.Prop2, e=> e.Prop3);
我知道这并不完全符合您的模式,但我认为您可以根据需要进行重构。
答案 1 :(得分:8)
我认为Paige Cook的代码不会如图所示。
我已经包含了一个应该改编的代码版本:
public TEntity GetById(Guid id, params Expression<Func<TEntity, object>>[] includeProperties)
{
if (id == Guid.Empty) return null;
IQueryable<TEntity> set = _unitOfWork.CreateSet<TEntity>();
foreach(var includeProperty in includeProperties)
{
set = set.Include(includeProperty);
}
return set.First(i => i.Id == id);
}
我只是通过跟踪Entity Framework生成的SQL来发现这一点,并且通过使用延迟加载来填充指定包含的实体,意识到原始代码只是给出了工作的错觉。
applying the Include statements using the LINQ Aggregate method实际上有一个更简洁的语法,它位于链接到的博客文章中。我的帖子还通过回退到Find方法稍微改进了方法,当不需要包含时,还显示了如何使用类似语法实现“GetAll”方法的示例。
答案 2 :(得分:0)
include方法可以在你的linq查询中串起来,如下所示:
var result = (from i in dbContext.TableName.Include("RelationProperty")
.Include("RelationProperty")
.Include("RelationProperty")
select i);
答案 3 :(得分:0)
出于多种原因,将上下文存储在非本地空间中是个坏主意。
我修改了Steve的代码并为我的ASP.NET MVC项目获取了这个代码:
public aspnet_User FirstElement(Func<aspnet_User, bool> predicate = null, params Expression<Func<aspnet_User, object>>[] includes)
{
aspnet_User result;
using (var context = new DataContext())
{
try
{
var set = context.Users.AsQueryable();
for (int i = 0; i < includes.Count(); i++ )
set = set.Include(includes[i]);
if (predicate != null)
result = set.ToList().FirstOrDefault(predicate);
else
result = set.ToList().FirstOrDefault();
}
catch
{
result = null;
}
}
return result;
}