泛型传递实体时属性重复,数据库未存预期值的问题排查
问题分析与修复方案
嘿,我一眼就看出问题出在哪了——你的Category子类重新声明了基类NestedSetEntity里的Id、Lft、Rgt、Depth和Tree属性,这就导致了属性隐藏的问题。
当你在MakeRootAsync方法中操作ownerNode(基类类型)的这些属性时,你实际上修改的是基类的属性,而子类自己声明的同名属性根本没被赋值。EF Core映射的时候,只会把子类的属性写入数据库,所以数据库里这些字段都是默认值0,完全符合预期——只是这个预期不是你想要的😂。
下面是具体的修复方案:
1. 清理子类的重复属性声明
把Category类中重复的基类属性全部删掉,只保留子类特有的属性。这样子类会直接继承基类的属性,EF Core也会正确映射这些属性到数据库表中:
[Table("categories")] public class Category : NestedSetEntity { public Category() { Visible = true; CreatedAt = DateTime.Now; UpdatedAt = DateTime.Now; } [Required] [StringLength(256)] [Column("title")] public string Title { get; set; } [Column("visible")] public bool Visible { get; set; } [Required] [Column("created_at")] public DateTime CreatedAt { get; set; } [Column("updated_at")] public DateTime UpdatedAt { get; set; } }
2. 优化基类(可选但推荐)
把基类标记为抽象类(因为你不会直接实例化它),并且给基类的属性加上[Column]特性,确保和数据库列名对应:
public abstract class NestedSetEntity { [Column("id")] public Guid Id { get; set; } [Column("lft")] public int Lft { get; set; } [Column("rgt")] public int Rgt { get; set; } [Column("depth")] public int Depth { get; set; } [Column("tree")] public Guid? Tree { get; set; } }
修复原理
现在Category类的Lft、Rgt等属性完全继承自基类,当你在MakeRootAsync中设置ownerNode.Lft = 1时,你修改的就是Category实例的对应属性,EF Core会把这些值正确写入数据库。而且这样也符合面向对象的继承原则,避免了重复代码和属性隐藏的坑。
如果你之前是因为担心列名映射问题才重复声明属性,现在基类的[Column]特性已经帮你解决了这个问题,完全不需要在子类里重复写一遍。
内容的提问来源于stack exchange,提问作者LANSELOT
相关产品推荐
相关产品推荐

