[英]ASP .NET Core disposing UnitOfWork before getting all data
I'm implementing a generic repository + Unit of work pattern along with a WebApi project. 我正在与WebApi项目一起实现通用存储库+工作单元模式。 I'm having problems with getting one entity and including the collection of another enttity that refers to it. 我在获取一个实体以及包含引用该实体的另一实体时遇到问题。
I have the following entities mapped through code first: 我首先通过代码映射了以下实体:
public class Ingredient : BaseEntity
{
public string Name { get; set; }
public string Amount { get; set; }
public Guid RecipeId { get; set; }
public virtual Recipe Recipe { get; set; }
}
public class Recipe : BaseEntity
{
public string Name { get; set; }
public string Description { get; set; }
public string ImagePath { get; set; }
public virtual ICollection<Ingredient> Ingredients { get; set; }
}
This is my unit of work: 这是我的工作单元:
public class UnitOfWork<TContext> : IRepositoryFactory, IUnitOfWork<TContext>, IUnitOfWork where TContext : DbContext
{
private readonly TContext context;
private Dictionary<Type, object> repositories;
public UnitOfWork(TContext context)
{
this.context = context ?? throw new ArgumentNullException(nameof(context));
}
public TContext Context => context;
public IRepository<TEntity> GetRepository<TEntity>() where TEntity : BaseEntity
{
if (repositories == null)
{
repositories = new Dictionary<Type, object>();
}
var type = typeof(TEntity);
if (!repositories.ContainsKey(type))
{
repositories.Add(type, new Repository<TEntity>(context));
}
return (IRepository<TEntity>)repositories[type];
}
public int Commit()
{
return context.SaveChanges();
}
public void Dispose()
{
context?.Dispose();
}
}
And my generic repository: 而我的通用存储库:
public class Repository<T> : IRepository<T> where T : BaseEntity
{
protected readonly DbContext dbContext;
protected readonly DbSet<T> dbSet;
public Repository(DbContext context)
{
dbContext = context;
dbSet = dbContext.Set<T>();
}
public T GetEntity(Guid id)
{
return dbSet.Find(id);
}
public T GetEntity(Guid id, params Expression<Func<T, object>>[] includeProperties)
{
IEnumerable<string> properties = GetProperties(includeProperties);
IQueryable<T> queryable = dbSet;
foreach (var property in includeProperties)
{
queryable = dbSet.Include(property);
}
return queryable.FirstOrDefault(x => x.Id == id);
}
[...]
private static IEnumerable<string> GetProperties(Expression<Func<T, object>>[] includeProperties)
{
List<string> includelist = new List<string>();
foreach (var item in includeProperties)
{
MemberExpression body = item.Body as MemberExpression;
if (body == null)
throw new ArgumentException("The body must be a member expression");
includelist.Add(body.Member.Name);
}
return includelist.AsEnumerable();
}
}
The controller is injecting the RecipeService. 控制器正在注入RecipeService。 In the controller I have this method: 在控制器中,我有这种方法:
[HttpGet("{id}", Name = "Get")]
public IActionResult Get(Guid id)
{
var recipe = recipeService.GetRecipe(id);
if (recipe == null)
{
return NotFound();
}
return Ok(recipe);
}
The recipe service injects the IUnitOfWork and has the following method: 配方服务将注入IUnitOfWork并具有以下方法:
public Recipe GetRecipe(Guid id)
{
return repository.GetEntity(id, r => r.Ingredients);
}
Also I have the services registered as follows: 我还注册了以下服务:
services.AddScoped<IRepositoryFactory, UnitOfWork<TContext>>();
services.AddScoped<IUnitOfWork, UnitOfWork<TContext>>();
services.AddScoped<IUnitOfWork<TContext>, UnitOfWork<TContext>>();
services.AddScoped<IRecipeService, RecipeService>();
My problem is when I'm getting a specified recipe(along with its ingredients) i got a "The connection has been restarted" error (in firefox). 我的问题是,当我得到指定的配方(及其配料)时,出现了“连接已重新启动”错误(在Firefox中)。 While debugging I can see that I have the recipe with its ingredients. 在调试时,我可以看到我有配方及其成分。 But when returning Ok(recipe) and mapping the result to the entities, the IUnitOfWork is disposed after getting the first ingredient. 但是,当返回Ok(recipe)并将结果映射到实体时,将在获取第一个成分后处置IUnitOfWork。
Anyone can help me out? 有人可以帮我吗? Thanks 谢谢
The problem was I was having a circular reference i wasn't getting any exception. 问题是我有一个循环引用,但没有任何异常。
I fixed by adding the following in the ConfigureServices method of the Startup class: 我通过在Startup类的ConfigureServices方法中添加以下内容来进行修复:
services.AddMvc().AddJsonOptions(options =>
{
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.