Entity Framework 对存储库的异步调用 returns 虚拟实体为 null
Entity Framework Async Call to Repository returns virtual entities as null
我实现了通用存储库。问题是我在主要返回类型中的虚拟类型为空。如何将它们包含在异步调用中?
这是我的类型:
public class Translation : Entity
{
public string Text { get; private set; }
public Guid TranslationKeyID { get; set; }
[ForeignKey("TranslationKeyID")]
public virtual TranslationKey TranslationKey { get; set; }
}
现在这是我希望 TranslationKey
实体也在我的结果中的方法,但我只得到 TranslationKeyId
。
我的服务方式:
public async Task<List<TranslationDto>> ListTanslationsAsync()
{
var translations = await _translationRepository.GetAllAsync().
if (translations != null)
{
return translations.ProjectedAs<List<TranslationDto>>();
}
return null;
}
写什么而不是 GetAllAsync()?
什么是 TranslationDto?您是如何围绕 EF 实现存储库模式的?简而言之,您可能关闭了延迟加载或者您没有调用 Include,但这里有更多关于如何使您的实现更好的信息。
我还围绕 EF 实现了存储库模式,但创建了一个通用存储库,其中的方法是通用的,而不是类型。该类型本身有一个 DbContext 的实例,并且方法对 Set 进行相应的调用,因此 DbContext 中没有硬编码的 DbSet 实例。这是您可以使用的示例,然后您可以使用 Autofac 或其他 IoC 框架将其连接在一起。
public interface IMyGenericRepository
{
TEntity Find<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class;
IQueryable<TEntity> Filter<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class;
}
public sealed class MyGenericRepository : IMyGenericRepository
{
private DbContext _dbContext;
public virtual TEntity Find<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class
{
return _dbContext.Set<TEntity>().FirstOrDefault(predicate);
}
public virtual IQueryable<TEntity> Filter<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class
{
return DbSet<TEntity>().Where(predicate).AsQueryable<TEntity>();
}
}
您可以对其进行调整,使其 return 成为 List 的一个实例,并通过在通用存储库中实现您的访问逻辑而将 Dto 全部省略。您也可以在必要时或默认情况下实施 async/await 关键字。
现在是第 2 部分,获取对象图中的对象。
这可以通过使用 Include 扩展来实现,以确保 EF 在检索对象时填充图形的一部分。这可以由调用者完成,或者您可以从您的通用存储库实现一个子类(继承)来调用 Include。上面的代码可以这样调用:
var result = await _genericRepository.Filter<Translation>(add lambda here).Include(x => TranslationKey).ToListAsync();
简而言之,使用这种模式有很多可能性,只是弄清楚你需要什么以及把它放在哪里。
我实现了通用存储库。问题是我在主要返回类型中的虚拟类型为空。如何将它们包含在异步调用中? 这是我的类型:
public class Translation : Entity
{
public string Text { get; private set; }
public Guid TranslationKeyID { get; set; }
[ForeignKey("TranslationKeyID")]
public virtual TranslationKey TranslationKey { get; set; }
}
现在这是我希望 TranslationKey
实体也在我的结果中的方法,但我只得到 TranslationKeyId
。
我的服务方式:
public async Task<List<TranslationDto>> ListTanslationsAsync()
{
var translations = await _translationRepository.GetAllAsync().
if (translations != null)
{
return translations.ProjectedAs<List<TranslationDto>>();
}
return null;
}
写什么而不是 GetAllAsync()?
什么是 TranslationDto?您是如何围绕 EF 实现存储库模式的?简而言之,您可能关闭了延迟加载或者您没有调用 Include,但这里有更多关于如何使您的实现更好的信息。
我还围绕 EF 实现了存储库模式,但创建了一个通用存储库,其中的方法是通用的,而不是类型。该类型本身有一个 DbContext 的实例,并且方法对 Set 进行相应的调用,因此 DbContext 中没有硬编码的 DbSet 实例。这是您可以使用的示例,然后您可以使用 Autofac 或其他 IoC 框架将其连接在一起。
public interface IMyGenericRepository
{
TEntity Find<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class;
IQueryable<TEntity> Filter<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class;
}
public sealed class MyGenericRepository : IMyGenericRepository
{
private DbContext _dbContext;
public virtual TEntity Find<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class
{
return _dbContext.Set<TEntity>().FirstOrDefault(predicate);
}
public virtual IQueryable<TEntity> Filter<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class
{
return DbSet<TEntity>().Where(predicate).AsQueryable<TEntity>();
}
}
您可以对其进行调整,使其 return 成为 List 的一个实例,并通过在通用存储库中实现您的访问逻辑而将 Dto 全部省略。您也可以在必要时或默认情况下实施 async/await 关键字。
现在是第 2 部分,获取对象图中的对象。 这可以通过使用 Include 扩展来实现,以确保 EF 在检索对象时填充图形的一部分。这可以由调用者完成,或者您可以从您的通用存储库实现一个子类(继承)来调用 Include。上面的代码可以这样调用:
var result = await _genericRepository.Filter<Translation>(add lambda here).Include(x => TranslationKey).ToListAsync();
简而言之,使用这种模式有很多可能性,只是弄清楚你需要什么以及把它放在哪里。