EF кодовое отношение сложного типа - PullRequest
2 голосов
/ 03 ноября 2011

У меня есть базовый класс для проверяемых объектов:

AuditableObject

public class AuditableObject : DomainObject, IAuditable
{
    ... some fields

   public AuditInfo AuditInfo
   {
        get;
        set;
   }
}

AuditInfo

public class AuditInfo : IAuditable
{

    public int CreatedByDbId
    {
        get;
        set;
    }

    public DateTime CreatedDate
    {
        get;
        set;
    }

    public int? AmendedByDbId
    {
        get;
        set;
    }

    public DateTime? AmendedDate
    {
        get;
        set;
    }
}

CreatedByDbId и AmendByDbId связаны с объектом SystemUser:

SystemUser

public class SystemUser
{
    public int SystemUserDbId
    {
        get;
        set;
    }

    public string Username
    {
        get;
        set;
    }
}

У меня есть класс Call , который наследуется от AuditableObject, который также имеет другие свойства SystemUser:

public class Call : AuditableObject
{
    ... some fields

    public SystemUser TakenBy { get; set;}
    public SystemUser CreatedBy { get; set; }
    public SystemUser CancelledBy { get; set;}
    public int CancelledByDbId {get; set;}
    public int TakenByDbId { get; set;}
}

Таблица базы данных вызовов

CREATE TABLE [dbo].[Call](
[CallDbId] [int] IDENTITY(1,1) NOT NULL,
[CancelledBy] [int] NULL,
[CreatedByDbId] [int] NOT NULL,
[CreatedDate] [datetime] NOT NULL,
[AmendedByDbId] [int] NULL,
[AmendedDate] [datetime] NULL,
[TakenBy] [int] NOT NULL)

Кажется, я не могу правильно сопоставить свои карты, например,

modelBuilder.ComplexType<AuditInfo>();
...// configuration for Call
this.Property(x => x.AuditInfo.AmendedByDbId).HasColumnName("AmendedByDbId");
this.Property(x => x.AuditInfo.AmendedDate).HasColumnName("AmendedDate");
this.Property(x => x.AuditInfo.CreatedByDbId).HasColumnName("CreatedByDbId");
this.Property(x => x.AuditInfo.CreatedDate).HasColumnName("CreatedDate");

this.Property(t => t.CancelledByDbId).HasColumnName("CancelledBy");
this.Property(t => t.TakenByDbId).HasColumnName("TakenBy");

this.HasRequired(t => t.TakenBy).WithMany().HasForeignKey(x => x.TakenByDbId);
this.HasRequired(t => t.CancelledBy).WithMany().HasForeignKey(x => x.CancelledByDbId);

и я всегда получаю ошибки во время выполнения, такие как:

Invalid column name 'SystemUser_SystemUserDbId'.
Invalid column name 'SystemUser_SystemUserDbId1'.
Invalid column name 'SystemUser_SystemUserDbId2'.
Invalid column name 'CreatedBy_SystemUserDbId'.

Не могу понять: (

1 Ответ

0 голосов
/ 03 ноября 2011

Последняя ошибка "Неверное имя столбца 'CreatedBy_SystemUserDbId'" может произойти, поскольку отсутствует сопоставление свойства навигации CreatedBy со столбцом внешнего ключа CreatedByDbId в базе данных. Это должно выглядеть так:

this.HasRequired(t => t.CreatedBy)
    .WithMany()
    .Map(c => c.MapKey("CreatedByDbId"));

Я не знаю причину трех других ошибок в данный момент.

Редактировать

При более внимательном рассмотрении у меня возникает ощущение, что эту модель будет действительно сложно или, возможно, невозможно отобразить.

  • У вас есть свойство навигации CreatedBy для класса Call, но свойство внешнего ключа CreatedByDbId для сложного типа AuditInfo базового класса AuditableObject. Я сомневаюсь, что вы можете определить в сопоставлении, что эти свойства принадлежат друг другу в одном и том же отношении к SystemUser.

  • Поэтому свойство навигации CreatedBy должно быть в AuditInfo, где находится внешний ключ CreatedByDbId. Но это невозможно, потому что вы не можете поместить свойство навигации в сложный тип.

  • Нужно ли использовать комплексный тип для AuditInfo? Разве вы не можете поместить его свойства прямо в AuditableObject:

    public class AuditableObject : DomainObject, IAuditable
    {
        ... some fields
    
        public int CreatedByDbId { get; set; }
        public DateTime CreatedDate { get; set; }
        public int? AmendedByDbId { get; set; }
        public DateTime? AmendedDate { get; set; }
    }
    
  • Если вы сделаете это, вы сможете переместить свойство навигации CreatedBy из сущности Call в базовый класс AuditableObject, где живет FK CreatedByDbId, а затем создать то же отображение, которое вы уже использовали. сделал для двух других свойств навигации, но на этот раз для базового класса:

    modelBuilder.Entity<AuditableObject>()
        .HasRequired(a => a.CreatedBy)
        .WithMany()
        .HasForeignKey(a => a.CreatedById);
    
...