我正在使用EF Core 2.0,并希望封装集合,以便在添加到集合时能够运行业务逻辑。 (见https://blog.oneunicorn.com/2016/10/28/collection-navigation-properties-and-fields-in-ef-core-1-1/)
当受保护的字段和公共getter属于同一类型时,这非常有用,但是我无法使用继承方案进行此操作。
我的代码大致如下:
public abstract class ItemBase
{
protected readonly List<DetailBase> _details = new List<DetailBase>();
protected void AddDetail(DetailBase detail)
{
_details.Add(detail);
// shared business logic
}
}
public abstract class DetailBase
{
// ...
}
public class DetailA : DetailBase
{
// ...
}
public class DetailB : DetailBase
{
// ...
}
public class ItemA : ItemBase
{
public IEnumerable<DetailA> Details => _details.Cast<DetailA>();
public void AddDetail(DetailA detail)
{
base.AddDetail(detail);
// specific business logic for A
}
}
public class ItemB : ItemBase
{
public IEnumerable<DetailB> Details => _details.Cast<DetailB>();
public void AddDetail(DetailB detail)
{
base.AddDetail(detail);
// specific business logic for B
}
}
但这会引发以下异常:
InvalidOperationException: The type of navigation property 'Details' on the entity type 'ItemA' is '<CastIterator>d__34<DetailA>' which does not implement ICollection<DetailA>. Collection navigation properties must implement ICollection<> of the target type.
如何在我的派生类中正确转换集合,以便可以使用公共getter 详细信息来访问它?
现在我已经通过复制派生类中的受保护字段来解决它,但这并不像上面的代码那样干净。
public class ItemA : ItemBase
{
protected readonly List<DetailA> _details = new List<DetailA>();
public IEnumerable<DetailA> Details => _details;
public void AddDetail(DetailA detail)
{
base.DoSharedLogicOnAdd(detail);
// specific business logic for A
}
}