我使用asp.net核心和实体框架。我有一个需要创建“关注”按钮的任务。 此刻,我的模型如下:
public class Following
{
[Key, Column(Order = 0), ForeignKey("UserId")]
public string UserId { get; set; }
[Key, Column(Order = 1), ForeignKey("FollowerId")]
public string FollowerId { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
public bool IsFollowing { get; set; }
}
我有一个关注和取消关注功能,它们看起来像这样:
public async Task<bool> Follow(string userId, string currentUserId)
{
var currentExist = await GetFollower(userId, currentUserId);
// insert if new
if (currentExist == null)
{
var newFollower = new Following()
{
FollowerId = currentUserId,
UserId = userId,
CreatedAt = DateTime.UtcNow,
UpdatedAt = DateTime.UtcNow,
IsFollowing = true
};
InsertFollower(newFollower);
// update counters
updateFollow(userId, currentUserId);
return true;
}
if (currentExist.IsFollowing)
return false;
currentExist.UpdatedAt = DateTime.UtcNow;
currentExist.IsFollowing = true;
context.Entry(currentExist);
// update counters
updateFollow(userId, currentUserId);
return true;
}
public async Task<bool> UnFollow(string userId, string currentUserId)
{
// this I get user from db
var exist = await GetFollower(userId, currentUserId);
if (exist == null || !exist.IsFollowing) return false;
exist.UpdatedAt = DateTime.UtcNow;
exist.IsFollowing = false;
context.Entry(exist).State = EntityState.Modified;
updateUnFollow(userId, currentUserId);
return true;
}
接下来,我叫SaveChangesAsync()
此功能更新用户计数器:
private async Task updateFollow(string userId, string currentUserId)
{
await context.Database.ExecuteSqlCommandAsync("UPDATE User SET FollowerCount = FollowerCount + 1 WHERE UserId = {0}", userId);
await context.Database.ExecuteSqlCommandAsync("UPDATE User SET FollowingCount = FollowingCount + 1 WHERE UserId = {0}", currentUserId);
}
private async Task updateUnFollow(string userId, string currentUserId)
{
await context.Database.ExecuteSqlCommandAsync("UPDATE User SET FollowerCount = FollowerCount - 1 WHERE UserId = {0}", userId);
await context.Database.ExecuteSqlCommandAsync("UPDATE User SET FollowingCount = FollowingCount - 1 WHERE UserId = {0}", currentUserId);
}
问题在于,如果我多次单击“关注”按钮。一次又一次地取消订阅和订阅。我会得到不正确的计数器值,此外,有时还会发生“并发”错误。换句话说,计数器值有时小于1,有时大于1,很少是正确的1。 这行是从数据库中删除还是更新都没关系。
我希望此功能看起来像github一样的“星形”按钮。
在Internet上,我设法找到有关“行版本化”的信息。但我想听听这项任务的完美解决方案。
答案 0 :(得分:1)
着眼于此-我认为解决此问题的最佳方法是更改模型。 您需要捕获关注者和关注者。
创建一个多对多表以存储关注者/关注者。
CREATE TABLE followingTable
(
FollowedUser Varchar(255), FollowingUser Varchar(255)
)
然后您的关注按钮插入到此表中(如果尚未插入)
然后而不是增加/减少以下/跟随者的计数 您可以根据“多对多表”计算值。
EG:
UPDATE U
SET FollowerCount = Count(FollowingUser)
FROM
User u
join followingTable ft
on u.UserId = Ft.FollowedUser
这种方法的优点在于,如果用户多次按下按钮,则不会给出错误的值。