EF Core 支持字段 - 将属性公开为另一种类型? [英] EF Core Backing fields - expose property as another type?

查看:19
本文介绍了EF Core 支持字段 - 将属性公开为另一种类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个 EF 实体类 Person,上面有一个 PhoneNumber.PhoneNumber 存储为字符串类型,但我希望 Person 上的所有访问都通过 Phone 进行,它具有一些不错的访问器功能,例如验证或 GetAreaCode().我想将它作为字符串返回到数据库中,但是在查询时我想将它作为 PhoneNumber 返回:

Assume I have an EF entity class Person, with a PhoneNumber on it. PhoneNumber is stored as a string type, but I want all accesses on the Person to go through Phone which has some nice accessor functions, e.g. validation or GetAreaCode(). I want to back it in the db as a string, but when queried for it I want to return it as a PhoneNumber:

public class Person {
    public PhoneNumber Phone { /* Some clever get/set logic here */ }

    private string _phoneNumber; // Backing field
}

或者我可以让 PhoneNumber 将自己存储为字符串吗?如果我只是通过删除上面的支持字段将它包含在模型中,EF 就会被构造函数(一个受保护的构造函数,其参数比一个字符串更多)和复制构造函数混淆 PhoneNumber(PhoneNumber other).我可以让 EF 以某种方式忽略那些吗?

Or can I get PhoneNumber to store itself as a string? If I simply include it in the model by removing the backing field above, EF gets confused by the constructors (a protected ctor with some more args than the one string) and also a copy ctor PhoneNumber(PhoneNumber other). Can i make EF ignore those somehow?

我对想法持开放态度...

I'm open to ideas...

推荐答案

我发现在 EF Core 2.0 中有效的唯一方法是创建一个带有 getter/setter 的公共属性 名称不匹配您的支持字段并将其标记为 NotMapped,如下所示:

The only way I've found that works in EF Core 2.0 is to create a public property with getters/setters with a name that does not match your backing field and mark it as NotMapped, like so:

    [NotMapped]
    [Display(Name = "Fire Type")]
    public Enums.FireType Type
    {
        get
        {
            Enums.FireType type;
            if (!Enum.TryParse(_fireType, out type))
                type = Enums.FireType.Fire; // default

            return type;
        }
        set
        {
            _fireType = value.ToString();
        }
    }
    
    private string _fireType;

然后在您的 DbContext 的 OnModelCreating 方法中,告诉它在数据库表上创建一个充当后备属性的列:

Then in your DbContext's OnModelCreating method, tell it to create a column on the database table that acts like a backing property:

        // backing properties
        modelBuilder.Entity<Fire>()
            .Property<string>("FireType")
            .HasField("_fireType")
            .UsePropertyAccessMode(PropertyAccessMode.Field);

这样,我终于能够创建一个成功的迁移,让我在我的模型上有一个私有字段,在模型上有一个公共转换属性,在我的数据库表中有一个正确命名的列.唯一的问题是公共属性和私有字段不能共享相同的名称(不共享相同的类型),但无论如何,情况不会如此.

With that, I was finally able to create a successful migration that allowed me to have a private field on my model, a public transformative property on the model, and a single properly-named column in my database table. The only catch is that the public property and the private field can't share the same name (without sharing the same type), but that wasn't going to be the case for you, anyway.

这篇关于EF Core 支持字段 - 将属性公开为另一种类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆