尝试将实体添加到 DbSet 时,列表和只读集合之间没有强制运算符

No Coercion Operator between list and read only collection when try to add entity to DbSet

我在尝试将新的 Author 对象添加到 AuthorsDbSet 时遇到以下错误,但不确定如何解决它。

{"No coercion operator is defined between types 'System.Collections.Generic.List1[Persistence.Entities.Book]' and 'System.Collections.ObjectModel.ReadOnlyCollection1[Persistence.Entities.Book]'."}

将实体添加到数据库集时导致异常的方法:

public async Task<Guid> CreateAuthorAsync(string name)
    {
        ArgValidator.ThrowIfNullEmptyOrWhiteSpace(name);
        using var context = _dbContextFactory.CreateDbContext();

        var author = Author.Create(name);
        context.Authors.Add(author);//this line throws the exception
        await context.SaveChangesAsync();
        return author.Id;
    }

作者Class

public class Author
{
    public Guid Id { get; }
    public string Name { get; }
    public ReadOnlyCollection<Book> Books => _books.AsReadOnly();
    private List<Book> _books = new List<Book>();

    private Author(Guid id, string name)
    {
        Id = id;
        Name = name;
    }

    public static Author Create(string name)
    {
        ArgValidator.ThrowIfNullEmptyOrWhiteSpace(name);
        return new Author(Guid.NewGuid(), name);
    }
}

图书Class

public class Book
{
    public Guid Id { get; }
    public string Title { get; }
    public string Description { get; }
    public Author Author { get; }
    public Guid AuthorId { get; }
    public bool Available { get; private set; }

    private Book(Guid id, string title, string description, bool available, Guid authorId)
    {
        Id = id;
        Title = title;
        Description = description;
        Available = available;
        AuthorId = authorId;
    }

    public static Book Create(string title, string description, Guid authorId)
    {
        ArgValidator.ThrowIfNullEmptyOrWhiteSpace(title);
        description = description ?? string.Empty;

        return new Book(Guid.NewGuid(), title, description, true, authorId);
    }

DbContext

public class LibraryContext: DbContext
{
    public DbSet<Book> Books { get; set; }
    public DbSet<Author> Authors { get; set; }

    public LibraryContext(DbContextOptions<LibraryContext> options)
    : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Book>(e =>
        {
            e.ToTable("Books", b => b.IsTemporal());
            e.HasKey(x => x.Id);
            e.Property(x => x.Title).IsRequired();
            e.Property(x => x.Description).IsRequired();
            e.Property(x => x.Available).IsRequired().HasDefaultValue(false);
            e.HasOne(book => book.Author).WithMany(author => author.Books).HasForeignKey(book => book.AuthorId);
        });

        modelBuilder.Entity<Author>(e =>
        {
            e.ToTable("Authors", a => a.IsTemporal());
            e.HasKey(x => x.Id);
            e.Property(x => x.Name).IsRequired();
            e.HasMany(author => author.Books).WithOne(book => book.Author);
            //not explicitly configuring field as there is no proper fluent api method for it.
            //
            //simply allow it to be pickedup in the background by convention.
        });
    }

我不确定这是由于 onModelCreating 代码不正确还是其他原因造成的。也许我需要为 List 和 Readonly 集合定义某种强制运算符,我该怎么做?

通过更改为 IList 和 IReadonlyCollection 解决了这个问题。留下问题,因为我在搜索时找不到类似的问题。

public class Author
{
    public Guid Id { get; }
    public string Name { get; }

    public IReadOnlyCollection<Book> Books => (_books as List<Book>).AsReadOnly();
    private IList<Book> _books = new List<Book>();

    private Author(Guid id, string name)
    {
        Id = id;
        Name = name;
    }

    public static Author Create(string name)
    {
        ArgValidator.ThrowIfNullEmptyOrWhiteSpace(name);
        return new Author(Guid.NewGuid(), name);
    }
}