[英]How to setup readonly collection property with backing field in EF Core 2.2
I am trying to create an entity class which will expose a related collection through a readonly property, like this:我正在尝试创建一个实体 class ,它将通过只读属性公开相关集合,如下所示:
public class MyEntity: Entity
{
public int Id{ get; private set; }
private IList<RelatedEntity> _relatedEntities = new List<RelatedEntity>();
public IReadOnlyList<RelatedEntity> RelatedEntities => _relatedEntities.ToList().AsReadOnly();
}
The builder class looks like this:生成器 class 如下所示:
public void Configure(EntityTypeBuilder<MyEntity> builder)
{
builder.HasKey(x=>x.Id);
builder.Property<IReadOnlyList<RelatedEntity>>("RelatedEntities")
.HasField("_relatedEntities ")
.UsePropertyAccessMode(PropertyAccessMode.Field);
}
It builds but crashes at runtime with the exception:它构建但在运行时崩溃,但以下情况除外:
InvalidOperationException: The specified field '_relatedEntities' of type 'IList' cannot be used for the property 'MyEntity.RelatedEntities ' of type 'IReadOnlyList'.
InvalidOperationException:“IList”类型的指定字段“_relatedEntities”不能用于“IReadOnlyList”类型的属性“MyEntity.RelatedEntities”。 Only backing fields of types that are assignable from the property type can be used.
只能使用可从属性类型分配的类型的支持字段。
Could you provide a working example how to deal with this issue?您能否提供一个如何处理此问题的工作示例?
EF core requires you to use concrete types for backing fields. EF 核心要求您使用具体类型作为支持字段。 You need to change your code to:
您需要将代码更改为:
private readonly List<RelatedEntity> _relatedEntities = new List<RelatedEntity>();
public IReadOnlyList<RelatedEntity> RelatedEntities => _relatedEntities.ToList();
The error message is loud and clear:错误信息响亮而清晰:
IList is not assignable to IReadOnlyList
IList 不可分配给 IReadOnlyList
Changing the property type to the same type as the backing field will do the trick.将属性类型更改为与支持字段相同的类型就可以了。
Because IEnumerable<T>
is read-only by default, this would be your best bet I believe.因为
IEnumerable<T>
默认情况下是只读的,所以我相信这将是您最好的选择。
public class MyEntity: Entity
{
public int Id { get; private set; }
private readonly List<RelatedEntity> _relatedEntities = _collection.ToList().AsReadOnly();
public IEnumerable<RelatedEntity> RelatedEntities => _relatedEntities;
}
Update your fluent API as follows:更新您的流利 API 如下:
builder.HasKey(x=>x.Id);
builder.Metadata.FindNavigation("RelatedEntities")
.UsePropertyAccessMode(PropertyAccessMode.Field);
For EF Core 2, I believe the backing field must be of type HashSet<T>
to be correctly recognized by the framework, so this should work:对于 EF Core 2,我相信支持字段必须是
HashSet<T>
类型才能被框架正确识别,所以这应该有效:
public class MyEntity {
private HashSet<RelatedEntity> _relatedEntities = new HashSet<RelatedEntity>();
public IReadOnlyCollection<RelatedEntity> RelatedEntities => _relatedEntities;
}
See also https://entityframeworkcore.com/knowledge-base/54840443/ef-core-one-to-many-relationships--icollection-or-hashset-另请参阅https://entityframeworkcore.com/knowledge-base/54840443/ef-core-one-to-many-relationships--icollection-or-hashset-
I ckeck this and it worked:我检查了一下,它起作用了:
private readonly List<RelatedEntity> _relatedEntitys;
public IReadOnlyCollection<RelatedEntity> RelatedEntitys => _relatedEntitys;
And configuration must be like below:并且配置必须如下所示:
builder.HasMany(x => x.RelatedEntitys)
.WithOne()
.IsRequired()
.HasForeignKey(x => x.RelatedEntityId)
.OnDelete(DeleteBehavior.Cascade);
builder.Metadata
.FindNavigation("RelatedEntitys")
.SetPropertyAccessMode(PropertyAccessMode.Field);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.