如何将自定义类用作实体的属性,并通过Entity Framework Core进行转换?

时间:2019-02-05 11:33:09

标签: c# entity-framework entity-framework-core

我正在尝试在我的应用程序中使用“每个层次的表”为各个级别的帐户建模。基本上有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进行转换,以在独立类(无继承)上工作,但是当我尝试使用继承和每个层次结构的表时却不能。这是否不受支持,或者我做错了什么?

0 个答案:

没有答案