简体   繁体   English

如何使用自定义 class 作为具有 Entity Framework Core 转换的实体的属性?

[英]How do you use a custom class as a property of an entity with a conversion with Entity Framework Core?

I am trying to model various levels of accounts using "Table Per Hierarchy" in my application.我正在尝试在我的应用程序中使用“每个层次结构的表”来 model 各种级别的帐户。 Basically there are 3 levels of account: Super, Partner and Standard.基本上有3个级别的帐户:超级,合作伙伴和标准。 They all share most of their properties, but the key difference is that Standard accounts are managed by a Super or Partner account.它们都共享大部分属性,但主要区别在于标准帐户由超级帐户或合作伙伴帐户管理。

I want to add an AccountType property to the Account base class that is a custom class, but is persisted to the database as a string.我想将AccountType属性添加到Account库 class 中,该属性是自定义 class,但作为 string 保存到数据库中。 I know you can add a conversion for properties via EF's fluent API, but I cannot get it to work for this scenario.我知道您可以通过 EF 的 fluent API 添加属性转换,但我无法让它在这种情况下工作。

This is how my classes are laid out:这就是我的课程的布局方式:

 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; }

And this is my DbContext :这是我的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 }); } }

When I try and add a migration I get the following error message:当我尝试添加迁移时,我收到以下错误消息:

The property or navigation 'AccountType' cannot be added to the entity type 'ManagingAccount' because a property or navigation with the same name already exists on entity type 'Account'.无法将属性或导航“AccountType”添加到实体类型“ManagingAccount”,因为实体类型“Account”上已存在同名的属性或导航。

But if I swap out the AccountTypeClass for this enum:但是,如果我为此枚举换出AccountTypeClass

 public enum AccountTypeEnum { Super, Partner, Standard }

And change the conversion to this (Where EnumHelper is just a little helper class that parses a string to an enum value):并将转换更改为此(其中EnumHelper只是一个小助手 class ,它将 string 解析为枚举值):

 builder.Entity<Account>().Property(p => p.AccountType).HasConversion(p => p.ToString(), p => EnumHelper.Parse<AccountTypeEnum>(p));

Everything works as expected.一切都按预期工作。

I can get the conversion to/from my AccountTypeClass to work on a standalone class (no inheritance), but not when I try using inheritance and table per hierarchy.我可以在独立的 class(无继承)上进行与AccountTypeClass的转换,但当我尝试使用 inheritance 和每个层次结构的表时,则不能。 Is this not supported or have I done something wrong?这是不支持还是我做错了什么?

I could be wrong, but I feel like your migrations are messed up right now.我可能是错的,但我觉得你的迁移现在搞砸了。 Have you tried deleting all your migrations and creating a fresh initial migration, just to verify your model is translatable?您是否尝试过删除所有迁移并创建新的初始迁移,只是为了验证您的 model 是可翻译的?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM