【问题标题】:NotMapped attribute keeps related property from saving?NotMapped 属性使相关属性无法保存?
【发布时间】:2014-01-13 13:45:47
【问题描述】:

我有一些在数据库中没有直接映射的属性,所以我使用的约定是让另一个变量映射到数据库,以及一个用于执行的公共变量我所有的实际工作。常见的是[将布尔属性映射到 char 列][1],但我也有一个 StatusID 属性,其 C# 枚举根据派生类型而不同。

我的公共属性具有[NotMapped] 属性,而我的内部属性具有[Column] 属性。我认为有些东西是因为公共属性没有被映射,所以它也阻止了其他属性被映射。

在我的项目中,我从一个抽象的 Message 基类开始:

[Table("tblMessage")]
public abstract class Message {
    [Column("msgIsSample")]
    [Required]
    internal string dbIsSample { get; set; }

    [Column("msgStatusID")]
    internal int? dbStatusId { get; set; }

    [NotMapped]
    public bool IsSample {
        get {
            return dbIsSample.ToUpper() == "Y";
        }
        set {
            dbIsSample = value ? "Y" : "N";
        }
    }

    public Message() {
        this.IsSample = false;
        this.dbStatusId = null;
    }
}

现在我只有一个实现基类的类,Request:

public class Request : Message {
    [NotMapped]
    public int Status {
        get {
            return this.dbStatusId.HasValue ? this.dbStatusId.Value : 1;
        }
        set {
            this.dbStatusId = value;
        }
    }

    public Request()
        : base() {
            this.Status = 1;
    }
}

这是我的上下文:

public class MyContext : DbContext {
    public DbSet<Message> Messages { get; set; }

    static MyContext() {
        Database.SetInitializer<MyContext>(null);
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder) {
        modelBuilder.Entity<Message>()
                    .Map<Request>(m => m.Requires("msgTypeID").HasValue(1));
    }
}

这是其他人遇到过的吗?尽管在 EF 团队添加额外的自定义映射之前,这看起来像是公认的约定,但我无法找到任何关于为什么这不起作用的信息。其他人一定遇到过这个问题。

当我尝试执行此代码时,我收到一个 DbUpdateException 说它无法将 NULL 插入到列“msgIsSample”中,因为我已经在表创建脚本中设置了它。这没有任何意义,因为 msgIsSample 默认为“N”。

【问题讨论】:

    标签: c#-4.0 inheritance code-first entity-framework-6


    【解决方案1】:

    不要设为internal,而是设为protected internal

    在运行时,EF 将动态子类化您的实体。这些扩展类称为dynamic proxies

    EF 无法设置您的属性,因为它没有访问权限。要让 EF 访问您的资源,它必须具有 publicprotected 访问权限。您仍然可以拥有internal 属性,但通过添加protected 修饰符来授予子类访问权限。

    [Table("tblMessage")]
    public abstract class Message {
        [Column("msgIsSample")]
        [Required]
        public string dbIsSample { get; protected internal set; }
    
        [Column("msgStatusID")]
        public int? dbStatusId { get; protected internal set; }
    

    【讨论】:

    • 谢谢!我试图阻止它们对 UI 层可见,并且完全忘记了这个要求。我确实喜欢您的protected internal set;,这将允许它们在查询中使用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-15
    • 1970-01-01
    • 1970-01-01
    • 2017-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多