我正在尝试在我的应用程序中使用“每个层次的表”为各个级别的帐户建模。基本上有3个级别的帐户:超级帐户,合作伙伴帐户和标准帐户。它们都共享大多数属性,但是主要区别在于标准帐户由超级帐户或合作伙伴帐户管理。
我想向AccountType
基类添加一个Account
属性,该基类是一个自定义类,但是作为字符串保留在数据库中。我知道您可以通过EF的流畅API添加属性的转换,但是我无法在这种情况下使用它。
这是我的班级布局方式:
public abstract class Account
{
[Key]
public int Id { get; set; }
[Required]
public AccountTypeClass AccountType { get; set; }
// other props omitted for brevity
}
public class StandardAccount : Account
{
[Required]
public int ManagingAccountId { get; set; }
[ForeignKey(nameof(ManagingAccountId))]
public ManagingAccount ManagingAccount { get; set; }
}
public abstract class ManagingAccount : Account
{
public ICollection<StandardAccount> Accounts { get; set; } = new List<StandardAccount>();
}
public class PartnerAccount : ManagingAccount { }
public class SuperAccount : ManagingAccount { }
public class AccountTypeClass
{
// other props omitted for brevity
private string value;
private AccountTypeClass(string value) => this.value = value;
public static AccountTypeClass Super => new AccountTypeClass(nameof(Super).ToLower());
public static AccountTypeClass Partner => new AccountTypeClass(nameof(Partner).ToLower());
public static AccountTypeClass Standard => new AccountTypeClass(nameof(Standard).ToLower());
public static AccountTypeClass Parse(string value)
{
switch(value)
{
case "super": return Super;
case "partner": return Partner;
case "standard": return Standard;
default: throw new NotImplementedException();
}
}
public override string ToString() => this.value;
}
这是我的DbContext
:
public class DataContext : DbContext
{
public DataContext(DbContextOptions options) : base(options)
{
}
public virtual DbSet<Account> Accounts { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder
.Entity<Account>()
.Property(p => p.AccountType)
.HasConversion(p => p.ToString(), p => AccountTypeClass.Parse(p));
builder.Entity<SuperAccount>().HasData(new SuperAccount() { Id = 1 });
builder.Entity<PartnerAccount>().HasData(new PartnerAccount() { Id = 2 });
builder.Entity<StandardAccount>().HasData(new StandardAccount() { Id = 3, ManagingAccountId = 1 });
}
}
当我尝试添加迁移时,出现以下错误消息:
不能将属性或导航“ AccountType”添加到实体类型“ ManagingAccount”,因为在实体类型“ Account”上已经存在具有相同名称的属性或导航。
但是如果我将AccountTypeClass
换成这个枚举:
public enum AccountTypeEnum { Super, Partner, Standard }
然后将转换更改为此(EnumHelper
只是一个将字符串解析为枚举值的小助手类):
builder
.Entity<Account>()
.Property(p => p.AccountType)
.HasConversion(p => p.ToString(), p => EnumHelper.Parse<AccountTypeEnum>(p));
一切正常。
我可以从AccountTypeClass
到/从我的Files.copy(Path source, Path target, CopyOption... options) throws IOException
进行转换,以在独立类(无继承)上工作,但是当我尝试使用继承和每个层次结构的表时却不能。这是否不受支持,或者我做错了什么?