2014-01-13 3 views
0

У меня есть несколько свойств, для которых у меня нет прямого сопоставления в базе данных, поэтому я использую соглашение о наличии другой переменной, сопоставленной с базой данных, и общедоступной переменной, которая будет использоваться для всех моей фактической работы. Обычным является [сопоставление логического свойства в столбце char] [1], но у меня также есть свойство StatusID, чье перечисление C# отличается от производного типа.Атрибут NotMapped сохраняет связанное свойство с сохранением?

Мое общедоступное свойство имеет атрибут [NotMapped], а мое внутреннее свойство имеет атрибут [Column]. Я думаю, что есть что-то, что, поскольку государственная собственность не отображается, она не позволяет отображать и другое свойство.

В моем проекте, я начинаю с абстрактным базовым классом сообщения:

[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».

ответ

1

Вместо этого internal, сделайте это protected internal.

Во время выполнения EF будет подклассифицировать вашу сущность динамически. Эти расширенные классы называются dynamic proxies.

EF не может установить вашу собственность, потому что у него нет доступа. Чтобы предоставить EF доступ к вашей собственности, он должен иметь либо public, либо protected. У вас все еще есть свойства 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; } 
+0

Спасибо! Я пытался удержать их от видимости слоя UI и полностью забыл об этом требовании. Мне нравится ваш «защищенный внутренний набор», который позволит им использоваться в запросах. – krillgar

Смежные вопросы