c# - 在 EFCore 中使用 DBContext 进行查询时,什么会导致 "Collection is read-only"异常?

标签 c# entity-framework-core-3.1

使用 DBContext 执行基本查询时出现以下异常,但我无法弄清楚。 它是一个控制台应用程序。

抛出的异常是:

        fail: Microsoft.EntityFrameworkCore.Query[10100]
          An exception occurred while iterating over the results of a query for context type 'JobAssist.Services.ArticleBankMgmt.Infrastructure.ArticleBankContext'.
          System.NotSupportedException: Collection is read-only.
             at System.Collections.ObjectModel.ReadOnlyCollection`1.System.Collections.Generic.ICollection<T>.Add(T value)
             at Microsoft.EntityFrameworkCore.Metadata.Internal.ClrICollectionAccessor`3.Add(Object entity, Object value, Boolean forMaterialization)
             at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.AddToCollection(INavigation navigation, InternalEntityEntry value, Boolean forMaterialization)
             at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalMixedEntityEntry.AddToCollection(INavigation navigation, InternalEntityEntry value, Boolean forMaterialization)
             at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.NavigationFixer.AddToCollection(InternalEntityEntry entry, INavigation navigation, InternalEntityEntry value, Boolean fromQuery)
             at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.NavigationFixer.SetReferenceOrAddToCollection(InternalEntityEntry entry, INavigation navigation, InternalEntityEntry value, Boolean fromQuery)
             at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.NavigationFixer.ToDependentFixup(InternalEntityEntry dependentEntry, InternalEntityEntry principalEntry, IForeignKey foreignKey, Boolean fromQuery)
             at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.NavigationFixer.InitialFixup(InternalEntityEntry entry, Boolean fromQuery)
             at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.NavigationFixer.TrackedFromQuery(InternalEntityEntry entry)
             at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntryNotifier.TrackedFromQuery(InternalEntityEntry entry)
             at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.MarkUnchangedFromQuery()
             at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.StartTrackingFromQuery(IEntityType baseEntityType, Object entity, ValueBuffer& valueBuffer)
             at Microsoft.EntityFrameworkCore.Query.QueryContext.StartTracking(IEntityType entityType, Object entity, ValueBuffer valueBuffer)
             at lambda_method(Closure , QueryContext , DbDataReader , ResultContext , ResultCoordinator )
             at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.CustomShaperCompilingExpressionVisitor.<PopulateIncludeCollection>g__ProcessCurrentElementRow|9_0[TIncludingEntity,TIncludedEntity](<>c__DisplayClass9_0`2& )
             at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.CustomShaperCompilingExpressionVisitor.PopulateIncludeCollection[TIncludingEntity,TIncludedEntity](Int32 collectionId, QueryContext queryContext, DbDataReader dbDataReader, ResultCoordinator resultCoordinator, Func`3 parentIdentifier, Func`3 outerIdentifier, Func`3 selfIdentifier, Func`5 innerShaper, INavigation inverseNavigation, Action`2 fixup, Boolean trackingQuery)
             at lambda_method(Closure , QueryContext , DbDataReader , ResultContext , Int32[] , ResultCoordinator )
             at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.MoveNext()
System.NotSupportedException: Collection is read-only.
   at System.Collections.ObjectModel.ReadOnlyCollection`1.System.Collections.Generic.ICollection<T>.Add(T value)
   at Microsoft.EntityFrameworkCore.Metadata.Internal.ClrICollectionAccessor`3.Add(Object entity, Object value, Boolean forMaterialization)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.AddToCollection(INavigation navigation, InternalEntityEntry value, Boolean forMaterialization)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalMixedEntityEntry.AddToCollection(INavigation navigation, InternalEntityEntry value, Boolean forMaterialization)
   at Microsoft.EntityFramew

代码是:

    var bank = articleBankContext.ArticleBanks.FirstOrDefault();
    Console.WriteLine(bank.Id);

在我的 DBContext 中,OnModelCreating 代码是:

        protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        if (modelBuilder == null)
        {
            throw new ArgumentNullException(nameof(modelBuilder));
        }

        // Build the model
        modelBuilder.ApplyConfiguration(new ClientRequestEntityTypeConfiguration());

        modelBuilder.Entity<ArticleBank>(ab =>
        {
            ab.OwnsMany(ab => ab.ArticleTags, at =>
            {
                at.WithOwner();
                at.Property<DateTime>("CreatedDate");
                at.Property<DateTime>("UpdatedDate");
                at.ToTable("ArticleBankTags");
            });
        });

        modelBuilder.Entity<ArticleBank>(ab =>
        {
            ab.OwnsMany(ab => ab.Sources, s =>
            {
                s.WithOwner();
                s.Property<DateTime>("CreatedDate");
                s.Property<DateTime>("UpdatedDate");
                s.ToTable("ArticleBankSources");
            });
        });

        modelBuilder.Entity<Article>().OwnsOne(a => a.JSeeker).OwnsOne(a => a.Name);

        modelBuilder.Entity<Article>().OwnsMany(a => a.Ratings, ar => ar.ToTable("ArticleRatings").OwnsOne(ar => ar.JSeeker).OwnsOne(js => js.Name));
        modelBuilder.Entity<Article>().OwnsOne(a => a.Source).WithOwner();
        modelBuilder.Entity<Article>().OwnsMany(a => a.Tags).WithOwner();

        modelBuilder.Entity<ArticleBank>().HasMany(s => s.Articles);

        ////Create Shadow Properties
        modelBuilder.Entity<ArticleBank>().Property<DateTime>("CreatedDate");
        modelBuilder.Entity<ArticleBank>().Property<DateTime>("UpdatedDate");
        modelBuilder.Entity<Article>().Property<DateTime>("CreatedDate");
        modelBuilder.Entity<Article>().Property<DateTime>("UpdatedDate");
        modelBuilder.Entity<Article>().ToTable("ArticleBankArticles");
    }

我怎么知道他们在谈论什么“只读集合”?我在解决方案的其他项目中没有遇到过这样的问题。我有一个“PrePopulateDB()”,它实际上使用相同的上下文并将适当的数据添加到数据库中。

以下是 ArticleBanK 中的声明:

我在构造函数中创建列表。

private readonly List<ArticleTag> _articleTags; 
public IEnumerable<ArticleTag> ArticleTags => _articleTags.AsReadOnly(); /
private readonly List<Article> _articles; 
public IEnumerable<Article> Articles => _articles.AsReadOnly();

还有什么奇怪的,在 DBContext.Model.DebugView 中没有 Sources 属性的字段:

  EntityType: ArticleBank
    Navigations:
      Articles (_articles, IEnumerable<Article>) Collection ToDependent Article
      ArticleTags (_articleTags, IEnumerable<ArticleTag>) Collection ToDependent ArticleBank.ArticleTags#ArticleTag
        Annotations:
          EagerLoaded: True
      Sources (no field, IEnumerable<ArticleSource>) Collection ToDependent ArticleBank.Sources#ArticleSource
        Annotations:
          EagerLoaded: True

最佳答案

我发现了问题。

我没有遵守约定。我的导航字段(Sources)和(_articleSources)的属性未对齐。

关于c# - 在 EFCore 中使用 DBContext 进行查询时,什么会导致 "Collection is read-only"异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62612389/

相关文章:

c# - 使用 Where 条件给出空值的列表集合过滤

C# Lambda 转换为 VB

c# - Solr 的 Sitecore (ContentSearch) SeachMaxResults 可以在运行时重新定义吗?

c# - 找不到类型或命名空间名称 'MySqlConnection'(是否缺少 using 指令或程序集引用?)

entity-framework-core - 导致 EF Core 3.1 查询失败的服务器评估问题是什么?

c# - 使用 formsauthentication 登录并使用 HttpContext.Current.User.Identity

c# - 列映射到未命名列

c# - Entity Framework Core 和 Cosmos DB。使用 LINQ 表达式读取实体

.net-core - 尽管没有进行任何更改,但为什么 EF Core 在每次迁移时都会更新种子 bool 字段?

c# - 使用 include Entity Framework core 3.1 时如何过滤嵌套对象