EF Core. Не знаю, как справиться с конфликтами параллелизма - PullRequest
0 голосов
/ 13 марта 2020

Я пытался выяснить, почему я не могу добавить новые записи, но могу правильно их обновить. Мне не повезло, и я изучил эту проблему по другим темам, поэтому я специально спрашиваю о моей ситуации.

EntityConfig и методы

public void Configure(EntityTypeBuilder<Story> builder)
    {
        builder.ToTable("Stories");
        builder.HasKey(x => x.Id);

        builder.HasOne(s => s.Author)
               .WithMany(a => a.Stories)
               .HasForeignKey(s => s.AuthorId);

        builder.OwnsMany(x => x.Ratings, x =>
        {
            x.WithOwner().HasForeignKey(x => x.StoryId);
            x.Property(x => x.Score);
            x.HasKey(y => new { y.StoryId, y.UserId });
            x.ToTable("Ratings");

        });
        builder.OwnsMany(x => x.Favorites, x =>
        {
            x.WithOwner().HasForeignKey(x => x.StoryId);
            x.HasKey(y => new { y.StoryId, y.UserId });
            x.ToTable("Favorites");
        });
    }

public void WriteRating(int userId, double newRating)
    {
        if (HasUserWrittenRating(userId))
        {
            Ratings.FirstOrDefault(c => c.UserId == userId && c.StoryId == this.Id).Score = newRating;
            AverageRating = Ratings.Average(r => r.Score);
        }
        else
        {
            Ratings.Add(new Rating() { StoryId = this.Id, Score = newRating, UserId = userId });
            AverageRating = ((AverageRating * NumberOfRatings - 1) + newRating) / NumberOfRatings;
        }
    }

private bool HasUserWrittenRating(int userId)
    {
        return Ratings.Any(rat => rat.UserId == userId);
    }

public async Task WriteRatingForStory(int storyId, int userId, int score)
    {
        // Get the story that was rated
        var story = await _dbContext.Stories.FirstOrDefaultAsync(story => story.Id == storyId);

        // Updating thestory with the new rating
        story.WriteRating(userId, score);

        //_dbContext.Stories.Update(story);

        // Save the updated story to the database
        var saved = false;
        while (!saved)
        {
            try
            {
                // Attempt to save changes to the database
                _dbContext.SaveChanges();
                saved = true;
            }
            catch (DbUpdateConcurrencyException ex)
            {
                foreach (var entry in ex.Entries)
                {
                    if (entry.Entity is Story)
                    {
                        var proposedValues = entry.CurrentValues;
                        var databaseValues = entry.GetDatabaseValues();

                        foreach (var property in proposedValues.Properties)
                        {
                            var proposedValue = proposedValues[property];
                            var databaseValue = databaseValues[property];

                            // TODO: decide which value should be written to database
                            // proposedValues[property] = <value to be saved>;
                        }

                        // Refresh original values to bypass next concurrency check
                        entry.OriginalValues.SetValues(databaseValues);
                    }
                    else
                    {
                        throw new NotSupportedException(
                            "Don't know how to handle concurrency conflicts for "
                            + entry.Metadata.Name);
                    }
                }
            }
        }
    }

Рейтинги Структура БД (UserId, StoryId - это Primary, Score as float)

Структура базы данных Stories (Id в качестве Primary, AuthorId, Title, Date, Score, AverageRating, Url)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...