【问题标题】:User is only able to like one post用户只能赞一个帖子
【发布时间】:2018-07-18 02:22:03
【问题描述】:

我有一个以 ApplicationUser 作为作者的 Books 类。在我的 ApplicationUser 类中,我有一个用户创作的书籍列表(一对多)。

Books 类还有一个 ApplicationUsers 列表,用于记录喜欢的数量。但是,单个 ApplicationUser 只能喜欢一本书。当用户喜欢另一本书时,喜欢的内容将从任何以前的书籍中删除。

public class ApplicationUser : IdentityUser
{
    public string Name { get; set; }

    public virtual ICollection<Book> Books { get; set; }
    public virtual ICollection<Book> Likes { get; set; } //NEW
}

public class Book
{
    public string Id { get; set; }

    public virtual ApplicationUser ApplicationUser { get; set; } //Author

    .......

    public virtual ICollection<ApplicationUser> Likes { get; set; }
}

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

         modelBuilder.Entity<Book>()
                .HasRequired<ApplicationUser>(s => s.ApplicationUser) 
                .WithMany(s => s.Books)
                .WillCascadeOnDelete(true); 

         modelBuilder.Entity<Book>() //NEW
                .HasMany<ApplicationUser>(s => s.Likes)
                .WithMany(s => s.Likes);
  }

一定是关系有问题。单个用户只能喜欢一本书。但是一个用户应该能够喜欢很多书。 book.Likes.Add(user);在检查用户是否存在对该书的“点赞”后,简单地添加了一个点赞。

但是 Book 和创建 Book 的 ApplicationUser 之间的一对多关系必须存在。但它们对 ApplicationUser 和 Likes 之间的关系没有要求。

[ResponseType(typeof(void))]
    public IHttpActionResult Like(string bookid, bool action)
    {
        Book book = db.Books.Find(bookid);
        var user = UserManager.FindById(User.Identity.GetUserId());
        if (book == null || user == null)
            return BadRequest();
        if (action)
        {
            if (!book.Likes.Contains(user))
                book.Likes.Add(user);
        }
        else
        {
            if (book.Likes.Contains(user))
                book.Likes.Remove(user);
        }
        //db.Entry(book).State = EntityState.Modified;

        try {
            db.SaveChanges();
        }
        catch (Exception e) {
            throw;
        }
        return StatusCode(HttpStatusCode.NoContent);
    }

更新:所以我按照@Alex Kudryashev 的建议将 Likes 集合添加到 ApplicationUser 类中。但是我现在在迁移和更新数据库时遇到了这个错误。

在表“BookApplicationUsers”上引入 FOREIGN KEY 约束“FK_dbo.BookApplicationUsers_dbo.AspNetUsers_ApplicationUser_Id”可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。 无法创建约束或索引。查看以前的错误。

【问题讨论】:

  • 您使用什么数据库技术?你能显示添加喜欢的完整代码吗?
  • 实体框架,代码优先。添加了喜欢的代码。谢谢@john
  • 为什么点赞是由书籍而不是用户存储的?您当前的关系是“用户喜欢图书”而不是“用户喜欢图书”。
  • @RenanB 因为我想在用户通过调用 book.Likes.Count 请求一本书时获得点赞数。
  • Likes 集合应该属于这两个类来解析many-to-many 关系。

标签: c# asp.net entity-framework


【解决方案1】:

你的问题的原因在于你对ApplicationUsersBooks之间的关系没有一个清晰的概念。

每个ApplicationUser 都有零个或多个Books 的作者,每个Book 都被零个或多个ApplicationUsers 点赞。因此ApplicationUsersBooks 之间的关系是多对多的。

在EF代码中首先是这样写的:

class ApplicationUser
{
    public int Id {get; set;}

    // every ApplicationUser has Authored zero or more books (many-to-many)
    public virtual ICollection<Book> AuthoredBooks {get; set;}

    ... // other properties
}
class Book
{
    public int Id {get; set;}

    // every Book has been Liked by zero or more ApplicationUsers (many-to-many)
    public virtual ICollection<ApplicationUsers> Likers {get; set;}

    ... // other properties
}

class MyDbContext : DbContext
{
     public DbSet<ApplicationUser> ApplicationUsers {get; set;}
     public DbSet<Book> Books {get; set;}
}

Configure many-to-many relationship

MyDbContext.OnModelCreating:

 modelBuilder.Entity<ApplicationUser>()
     // every applicationUser has zero or more AuthoredBooks
     .HasMany(applicationUser => applicationUser.AuthoredBooks)

     // where every Book has zero or more Likers:
     .WithMany(book => book.Likers)

     // we put the many-to-many in the following junction table:
     .Map(junctionTable=>
     {
         junctionTable.MapLeftKey("ApplicationUserId");
         junctionTable.MapRightKey("BookId");
         junctionTable.ToTable("ApplicationUsersBooks");
      });

与多对多一样,虽然创建了联结表,但您没有在dbContext 中提及它。每当你使用 ICollection 时,实体框架就会知道 GroupJoin 需要联结表。

获取所有撰写过老书的年轻 ApplicationUser:

var result = myDbContext.ApplicationUsers
    .Where(user => user.BirtDate > new DateTime(2010, 1, 1)
    .Select(user => new
    {
         Id = user.Id,
         Name = user.Name,
         AuthoredOldBooks = user.Books
             .Where(book => book.PublicationDate < new DateTime(1900, 1, 1)
             .ToList(),
    }

或获取一位或多位女性喜欢的所有软件书籍:

var results = myDbContext.Books
    .Where(book => book.Genre ==  BookGenre.Software
       && book.Likers.Where(liker => liker.Gender == Gender.Female).Any());

【讨论】:

    猜你喜欢
    • 2019-03-10
    • 1970-01-01
    • 2018-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多