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

问题描述

假设我有一个EF实体类Person,上面有一个PhoneNumber。 PhoneNumber以字符串类型存储,但是我希望对Person的所有访问都通过Phone,Phone具有一些不错的访问器功能,例如验证或 GetAreaCode()。我想将它作为字符串备份到db中,但是当查询它时,我想将其作为电话号码返回:

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会被构造函数(一个受保护的ctor,比一个字符串具有更多的arg)感到困惑,并且还会复制ctor 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中使用的唯一方法是创建一个具有getters / setters 名称与您的后备字段不匹配的公共属性,并将其标记为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核心支持字段-将属性公开为另一种类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-26 23:02