我正在寻找应该往哪个方向的建议。
我有一个带有寄存器类型的统一容器:
UnityConfig.cs
public static void RegisterTypes(IUnityContainer container)
{
container.RegisterType<IRepository<ActivityExtendedData>, repository<ActivityExtendedData, IntranetContext>>(new HierarchicalLifetimeManager(), new InjectionConstructor());
}
和基于https://stackoverflow.com/a/46674036
的存储库实现Repository.cs
public class Repository<TDbSet, TDbContext> : IRepository<TDbSet> where TDbSet : class where TDbContext : DbContext, new()
{
internal DbContext _context;
internal DbSet<TDbSet> _dbSet;
public Repository(DbContext context)
{
_context = context;
_dbSet = _context.Set<TDbSet>();
}
public Repository() : this(new TDbContext())
{
}
public Repository(string database = null)
{
SetDatabase(database);
}
public void SetDatabase(string database)
{
var dbConnection = _context.Database.Connection;
if (string.IsNullOrEmpty(database) || dbConnection.Database == database)
return;
if (dbConnection.State == ConnectionState.Closed)
dbConnection.Open();
_context.Database.Connection.ChangeDatabase(database);
}
}
public virtual async Task<IEnumerable<TDbSet>> Get(
Expression<Func<TDbSet, bool>> filter = null,
Func<IQueryable<TDbSet>, IOrderedQueryable<TDbSet>> orderBy = null,
string includeProperties = "",
int limit = 1000)
{
IQueryable<TDbSet> query = _dbSet;
if (filter != null)
{
query = query.Where(filter);
}
foreach (var includeProperty in includeProperties.Split
(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProperty);
}
if (orderBy != null)
{
return await orderBy(query).Take(limit).ToListAsync();
}
else
{
return await query.Take(limit).ToListAsync();
}
}
由控制器调用:
ActivityController
public class ActivityController : Controller
{
private readonly IRepository<ActivityExtendedData> _activityRepo;
public ActivityController(IRepository<ActivityExtendedData> activityRepo)
{
_activityRepo = activityRepo;
}
[Authorize]
public async Task<ActionResult> Index(int limit = 100)
{
return View(
await _activityRepo.Get(
limit: limit,
orderBy: s => s.OrderByDescending(q => q.DateAdd),
includeProperties: "Request,Response,User,Other"
));
}
使用上述配置,我收到异常:
System.NotSupportedException:在先前的异步操作完成之前,第二个操作在此上下文上启动。使用“ await”来确保在此上下文上调用另一个方法之前,所有异步操作都已完成。不保证任何实例成员都是线程安全的。 [...] 在Intranet.EntityFramework \ DAL \ Repository.cs:row 94中的EntityFramework.DAL.Repository`2.d__8.MoveNext()中 [...] 在Portal.Controllers.ActivityController.d__2.MoveNext()处,通过Intranet.Portal \ Controllers \ ActivityController.cs:row 24
Repository.cs:第94行if (orderBy != null)
,ActivityController.cs:第24行await _activityRepo.Get(
我不知道如何在Repository()中更改Get()方法,并在其中放置正确的await方法。
所以我修改了 UnityConfig.cs
public static void RegisterTypes(IUnityContainer container)
{
container.RegisterType<IntranetContext>(new PerRequestLifetimeManager());
container.RegisterType<IRepository<ActivityExtendedData>, Repository<ActivityExtendedData, IntranetContext>>(new PerRequestLifetimeManager(), new InjectionConstructor());
}
可能不需要行container.RegisterType<IntranetContext>(new PerRequestLifetimeManager());
。
但是现在我需要为每个请求接收新的Context和Repository实例,并且当然不会出现异常。但这是一个好方法吗?