尝试将实体添加到 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.ReadOnlyCollection
1[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);
}
}
我在尝试将新的 Author 对象添加到 AuthorsDbSet 时遇到以下错误,但不确定如何解决它。
{"No coercion operator is defined between types 'System.Collections.Generic.List
1[Persistence.Entities.Book]' and 'System.Collections.ObjectModel.ReadOnlyCollection
1[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);
}
}