新しい IdentityDbContext を使用しながら、多数の MVC 4 アプリケーションで使用した UnitOfWork パターンを MVC 5 に拡張しようとしていますが、うまくいきません。問題は、エラーが生成されていないため、デバッグが非常に難しいことです。
まず、いくつかのコード。
次のようなコンテキスト定義があります。すべてを 1 か所に保持することが理にかなっているため、独自の DbSet をそのままの IdentityDbContext に追加しました。
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public DbSet<PALSOfficer> PALSOfficers { get; set; }
public DbSet<Client> Clients { get; set; }
public DbSet<GP> GPs { get; set; }
public DbSet<Surgery> Surgeries { get; set; }
public DbSet<Disability> Disabilities { get; set; }
public DbSet<Area> Areas { get; set; }
public DbSet<PALSReferral> PALSReferrals { get; set; }
public DbSet<Appointment> Appointments { get; set; }
public ApplicationDbContext()
: base("DefaultConnection")
{
}
}
次に、次のような UnitOfWork クラスがあります。
public class UnitOfWork : IDisposable
{
private bool _disposed = false;
private ApplicationDbContext _context = new ApplicationDbContext();
public UserManager<ApplicationUser> _userManager { get; set; }
private PalsOfficerRepository _palsOfficerRepository;
private UserRepository _userRepository;
private GenericRepository<Area> _areaRepository;
public UserRepository UserRepository
{
get
{
if (this._userRepository == null)
{
this._userRepository = new UserRepository(_context);
}
return _userRepository;
}
}
public PalsOfficerRepository PalsOfficerRepository
{
get
{
if (this._palsOfficerRepository == null)
{
this._palsOfficerRepository = new PalsOfficerRepository(_context);
}
return _palsOfficerRepository;
}
}
public GenericRepository<Area> AreaRepository
{
get
{
if (this._areaRepository == null)
{
this._areaRepository = new GenericRepository<Area>(_context);
}
return _areaRepository;
}
}
public UserManager<ApplicationUser> UserManager
{
get
{
if (this._userManager == null)
{
this._userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(_context));
}
return _userManager;
}
}
public void Save()
{
try
{
_context.SaveChanges();
}
catch (DbEntityValidationException dbEx)
{
foreach (var validationErrors in dbEx.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
Trace.TraceInformation("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);
}
}
throw;
}
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (this._userManager != null)
{ this._userManager.Dispose(); }
_userManager.Dispose();
}
this._disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
ここまでは順調ですね。最初にコードを使用して、自動移行でデータベースを生成しています。
私の問題は、データベースにクエリを実行しようとすると、奇妙なことが起こることです。この方法を例にとってみましょう。
var results = new SearchResults<PALSOfficer>();
var officers = from o in Context.PALSOfficers
select o;
if (!string.IsNullOrEmpty(keyword))
{
officers = (from o in officers
where o.FirstName.Contains(keyword) || o.LastName.Contains(keyword)
select o);
}
officers = officers.OrderBy(p => p.LastName);
results.Total = officers.Count();
int offset = page * display;
results.ResultList = results.Total > offset ? officers.Skip(offset).Take(display) : officers;
//results.ResultList = Context.PALSOfficers;
return results;
データベースにデータが含まれていても、これは何も返しません。奇妙なことに、カウントは機能します。ブレークポイントを配置して結果にマウスオーバーすると、「子を評価できませんでした」というメッセージが表示されます
単純に戻るContext.PALSOfficers
と、行が返されます。ただし、そのデータの操作(並べ替えなど)はすべて、クエリを完全に壊しているようです。
これがPALSOfficerの定義です
public class ApplicationUser : IdentityUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public DateTime Added { get; set; }
public DateTime Updated { get; set; }
}
public class PALSOfficer : ApplicationUser
{
public string InternalReference { get; set; }
public virtual ICollection<Area> Areas { get; set; }
}