Я использую ядро и сущность 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.
В интернете мне удалось найти информацию о «rowversion».Но я хотел бы услышать идеальное решение для этой задачи.