Question

I have a few properties that I don't have a direct mapping in the database for, so I'm using the convention of having another variable that is mapped to the database, and a public variable that will be used to do all of my actual work. The common one is [mapping a boolean property to a char column][1], but I also have a StatusID property whose C# enum is different based on the derived type.

My public property has the [NotMapped] attribute on it, and my internal property has the [Column] attribute. I think there's something that because the public property isn't mapped, it's keeping the other property from being mapped as well.

In my project, I start with an abstract base Message class:

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

Right now I only have a single class implementing the base class, 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;
    }
}

Here is my context:

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

Is this something that anyone else has run across? I haven't been able to find anything about why this isn't working, even though this looks like the accepted convention until the EF team adds additional custom mapping. Someone else has to have run across this issue.

When I try to execute this code, I get a DbUpdateException saying that it can't insert a NULL into column "msgIsSample" due to my having set that in the table creation script. This doesn't make any sense because the msgIsSample is defaulted to have a "N".

Was it helpful?

Solution

Instead of making it internal, make it protected internal.

At runtime, EF will subclass your entity dynamically. These extended classes are called dynamic proxies.

EF cannot set your property because it does not have access. To give EF access to your property, it must have either public or protected access. You can still have internal properties, but give subclasses access by adding the protected modifier.

[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; }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top