如何访问链接表
我刚刚通过实体框架Core 6.0实现了两个模型,漫画和流派之间的许多关系,该模型在我的数据库中创建了链接表GenRemanga。我正在尝试访问与特定漫画相关的所有类型,但我坚持尝试访问链接表。我的解决方案遵循存储库结构和工作模式单位。
在这个类似问题上的stackoverflow答案使我达到了这种格式:
var genres = _unitOfWork.GenreMangas.Include(a => a.Genres);
但是,我无法像其他Stackoverflow用户那样访问链接表,我会收到此错误:
'iunitofwork'不包含“ genremangas”的定义,也没有可访问的扩展方法'genremangas'接受类型“ iunitofwork”的第一个参数(您是否缺少使用指令或汇编引用?)
也许我需要更改?我如何定义和使用一些东西?我什至不确定从哪里开始。如果有人可以将我指向正确的方向,我将不胜感激。
以下是我的很多课程,但我希望它可以解释结构(或混乱)。
public class Manga
{
public int Id { get; set; }
[Required]
public string Title { get; set; }
[Required]
public string Description { get; set; }
public string Status { get; set; }
public int Chapters { get; set; }
public DateTime Updated { get; set; }
[Range(1,5)]
public double Rating { get; set; }
public int Views { get; set; }
[ValidateNever]
public string ImageUrl { get; set; }
public ICollection<Genre>? Genres { get; set; }
[Required]
[Display(Name = "Author")]
public int AuthorId { get; set; }
[ValidateNever]
public Author Author { get; set; }
}
public class Genre
{
[Key]
public int Id { get; set; }
[Required]
public string Name { get; set; }
public ICollection<Manga>? Mangas { get; set; }
}
public class MangaVM
{
public Manga Manga { get; set; }
[ValidateNever]
public List<Genre>? Genres { get; set; }
[ValidateNever]
public List<string> GenresList { get; set; }
[ValidateNever]
public IEnumerable<SelectListItem> AuthorList { get; set; }
}
public class ApplicationDbContext : IdentityDbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
}
public DbSet<Genre> Genres { get; set; }
public DbSet<Author> Authors { get; set; }
public DbSet<Manga> Mangas { get; set; }
public DbSet<Page> Pages { get; set; }
public DbSet<Chapter> Chapters { get; set; }
public DbSet<ApplicationUser> ApplicationUsers { get; set; }
}
public class UnitOfWork : IUnitOfWork
{
private ApplicationDbContext _dbContext;
public UnitOfWork(ApplicationDbContext dbContext)
{
_dbContext = dbContext;
Genre = new GenreRepository(_dbContext);
Author = new AuthorRepository(_dbContext);
Manga = new MangaRepository(_dbContext);
Page = new PageRepository(_dbContext);
Chapter = new ChapterRepository(_dbContext);
}
public IGenreRepository Genre { get; private set; }
public IAuthorRepository Author { get; private set; }
public IMangaRepository Manga { get; private set; }
public IPageRepository Page { get; private set; }
public IChapterRepository Chapter { get; private set; }
public void Save()
{
_dbContext.SaveChanges();
}
}
public interface IUnitOfWork
{
IGenreRepository Genre { get; }
IAuthorRepository Author { get; }
IMangaRepository Manga { get; }
IPageRepository Page { get; }
IChapterRepository Chapter { get; }
void Save();
}
public class MangaRepository : Repository<Manga>, IMangaRepository
{
private ApplicationDbContext _dbContext;
public MangaRepository(ApplicationDbContext dbContext) : base(dbContext)
{
_dbContext = dbContext;
}
public void Update(Manga obj)
{
var objFromDb = _dbContext.Mangas.FirstOrDefault(a => a.Id == obj.Id);
if (objFromDb != null)
{
objFromDb.Title = obj.Title;
objFromDb.Description = obj.Description;
objFromDb.Status = obj.Status;
objFromDb.Chapters = obj.Chapters;
objFromDb.Updated = obj.Updated;
objFromDb.Rating = obj.Rating;
objFromDb.Views = obj.Views;
objFromDb.AuthorId = obj.AuthorId;
if (obj.ImageUrl != null)
{
objFromDb.ImageUrl = obj.ImageUrl;
}
}
}
}
public interface IMangaRepository : IRepository<Manga>
{
void Update(Manga obj);
}
public class Repository<T> : IRepository<T> where T : class
{
private readonly ApplicationDbContext _dbContext;
internal DbSet<T> dbSet;
public Repository(ApplicationDbContext dbContext)
{
_dbContext = dbContext;
//_dbContext.Mangas.Include(a => a.Genre).Include(a=>a.Author);
this.dbSet = _dbContext.Set<T>();
}
public void Add(T entity)
{
dbSet.Add(entity);
}
//includeProp - "Genre,Author"
public IEnumerable<T> GetAll(string? includeProperties = null)
{
IQueryable<T> query = dbSet;
if(includeProperties != null)
{
foreach(var includeProp in includeProperties.Split(new char[] {','}, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProp);
}
}
return query.ToList();
}
public IEnumerable<T> GetDataFromDbSetUsingFk(Expression<Func<T, bool>> filter, string? includeProperties = null)
{
IQueryable<T> query = dbSet;
query = query.Where(filter);
if (includeProperties != null)
{
foreach (var includeProp in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProp);
}
}
return query.ToList();
}
public T GetFirstOrDefault(Expression<Func<T, bool>> filter, string? includeProperties = null)
{
IQueryable<T> query = dbSet;
query = query.Where(filter);
if (includeProperties != null)
{
foreach(var includeProp in includeProperties.Split(new char[] {','}, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProp);
}
}
return query.FirstOrDefault();
}
public void Remove(T entity)
{
dbSet.Remove(entity);
}
public void RemoveRange(IEnumerable<T> entity)
{
dbSet.RemoveRange(entity);
}
}
public interface IRepository<T> where T : class
{
//T - Genre
T GetFirstOrDefault(Expression<Func<T, bool>> filter, string? includeProperties = null);
IEnumerable<T> GetDataFromDbSetUsingFk(Expression<Func<T, bool>> filter, string? includeProperties = null);
IEnumerable<T> GetAll(string? includeProperties = null);
void Add(T entity);
void Remove(T entity);
void RemoveRange(IEnumerable<T> entity);
}
编辑:尝试使用建议的使用此代码,但似乎有效,但类型是无效的,即使GenRemanga表中有两个记录,用于该漫画ID。我仍然觉得它根本无法访问链接表。
var mangaGenres = _unitOfWork.Manga.GetAll().Where(a => a.Id == id).SelectMany(a => a.Genres);
I just implemented the many to many relationship between two models, Manga and Genre through entity framework core 6.0 which created the link table GenreManga in my database. I am trying to access all genres that are related to a specific manga, but I am stuck on trying to access the link table. My solution follows the repository structure and unit of work pattern.
The stackoverflow answers on this similar question lead me to this format:
var genres = _unitOfWork.GenreMangas.Include(a => a.Genres);
However, I can't access the link table like other stackoverflow users and I get this error:
'IUnitOfWork' does not contain a definition for 'GenreMangas' and no accessible extension method 'GenreMangas' accepting a first argument of type 'IUnitOfWork' could be found (are you missing a using directive or an assembly reference?)
Maybe I need to change how I define and use some things? I'm not even sure where to begin. If anyone can point me in the right direction, I'd appreciate it.
Below is a lot of my classes, but I hope it explains the structure (or disorganization).
public class Manga
{
public int Id { get; set; }
[Required]
public string Title { get; set; }
[Required]
public string Description { get; set; }
public string Status { get; set; }
public int Chapters { get; set; }
public DateTime Updated { get; set; }
[Range(1,5)]
public double Rating { get; set; }
public int Views { get; set; }
[ValidateNever]
public string ImageUrl { get; set; }
public ICollection<Genre>? Genres { get; set; }
[Required]
[Display(Name = "Author")]
public int AuthorId { get; set; }
[ValidateNever]
public Author Author { get; set; }
}
public class Genre
{
[Key]
public int Id { get; set; }
[Required]
public string Name { get; set; }
public ICollection<Manga>? Mangas { get; set; }
}
public class MangaVM
{
public Manga Manga { get; set; }
[ValidateNever]
public List<Genre>? Genres { get; set; }
[ValidateNever]
public List<string> GenresList { get; set; }
[ValidateNever]
public IEnumerable<SelectListItem> AuthorList { get; set; }
}
public class ApplicationDbContext : IdentityDbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
}
public DbSet<Genre> Genres { get; set; }
public DbSet<Author> Authors { get; set; }
public DbSet<Manga> Mangas { get; set; }
public DbSet<Page> Pages { get; set; }
public DbSet<Chapter> Chapters { get; set; }
public DbSet<ApplicationUser> ApplicationUsers { get; set; }
}
public class UnitOfWork : IUnitOfWork
{
private ApplicationDbContext _dbContext;
public UnitOfWork(ApplicationDbContext dbContext)
{
_dbContext = dbContext;
Genre = new GenreRepository(_dbContext);
Author = new AuthorRepository(_dbContext);
Manga = new MangaRepository(_dbContext);
Page = new PageRepository(_dbContext);
Chapter = new ChapterRepository(_dbContext);
}
public IGenreRepository Genre { get; private set; }
public IAuthorRepository Author { get; private set; }
public IMangaRepository Manga { get; private set; }
public IPageRepository Page { get; private set; }
public IChapterRepository Chapter { get; private set; }
public void Save()
{
_dbContext.SaveChanges();
}
}
public interface IUnitOfWork
{
IGenreRepository Genre { get; }
IAuthorRepository Author { get; }
IMangaRepository Manga { get; }
IPageRepository Page { get; }
IChapterRepository Chapter { get; }
void Save();
}
public class MangaRepository : Repository<Manga>, IMangaRepository
{
private ApplicationDbContext _dbContext;
public MangaRepository(ApplicationDbContext dbContext) : base(dbContext)
{
_dbContext = dbContext;
}
public void Update(Manga obj)
{
var objFromDb = _dbContext.Mangas.FirstOrDefault(a => a.Id == obj.Id);
if (objFromDb != null)
{
objFromDb.Title = obj.Title;
objFromDb.Description = obj.Description;
objFromDb.Status = obj.Status;
objFromDb.Chapters = obj.Chapters;
objFromDb.Updated = obj.Updated;
objFromDb.Rating = obj.Rating;
objFromDb.Views = obj.Views;
objFromDb.AuthorId = obj.AuthorId;
if (obj.ImageUrl != null)
{
objFromDb.ImageUrl = obj.ImageUrl;
}
}
}
}
public interface IMangaRepository : IRepository<Manga>
{
void Update(Manga obj);
}
public class Repository<T> : IRepository<T> where T : class
{
private readonly ApplicationDbContext _dbContext;
internal DbSet<T> dbSet;
public Repository(ApplicationDbContext dbContext)
{
_dbContext = dbContext;
//_dbContext.Mangas.Include(a => a.Genre).Include(a=>a.Author);
this.dbSet = _dbContext.Set<T>();
}
public void Add(T entity)
{
dbSet.Add(entity);
}
//includeProp - "Genre,Author"
public IEnumerable<T> GetAll(string? includeProperties = null)
{
IQueryable<T> query = dbSet;
if(includeProperties != null)
{
foreach(var includeProp in includeProperties.Split(new char[] {','}, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProp);
}
}
return query.ToList();
}
public IEnumerable<T> GetDataFromDbSetUsingFk(Expression<Func<T, bool>> filter, string? includeProperties = null)
{
IQueryable<T> query = dbSet;
query = query.Where(filter);
if (includeProperties != null)
{
foreach (var includeProp in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProp);
}
}
return query.ToList();
}
public T GetFirstOrDefault(Expression<Func<T, bool>> filter, string? includeProperties = null)
{
IQueryable<T> query = dbSet;
query = query.Where(filter);
if (includeProperties != null)
{
foreach(var includeProp in includeProperties.Split(new char[] {','}, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProp);
}
}
return query.FirstOrDefault();
}
public void Remove(T entity)
{
dbSet.Remove(entity);
}
public void RemoveRange(IEnumerable<T> entity)
{
dbSet.RemoveRange(entity);
}
}
public interface IRepository<T> where T : class
{
//T - Genre
T GetFirstOrDefault(Expression<Func<T, bool>> filter, string? includeProperties = null);
IEnumerable<T> GetDataFromDbSetUsingFk(Expression<Func<T, bool>> filter, string? includeProperties = null);
IEnumerable<T> GetAll(string? includeProperties = null);
void Add(T entity);
void Remove(T entity);
void RemoveRange(IEnumerable<T> entity);
}
EDIT: Tried using this code as suggested and appears to work but genres is null even though there are two records in genremanga table for the for that manga Id. I still feel like it is not accessing the link table at all.
var mangaGenres = _unitOfWork.Manga.GetAll().Where(a => a.Id == id).SelectMany(a => a.Genres);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
没有多余的抽象,很容易:
请记住,
dbcontext
已经是工作单位,dbset
已经是存储库,Without superfluous abstraction it is easy:
Remember that
DbContext
is already Unit of Work andDbSet
is already repository,