2017-02-01 19 views
1

У меня есть база данных со следующей структурой:Entity Framework 6: Создание 0..0: 1 отображение, где обе таблицы имеют внешние ключи различных типов

Create Table Employees 
(
    EmployeeId INT NOT NULL PRIMARY KEY, 
    Name NVARCHAR(20) NOT NULL, 
    CertificationId UNIQUEIDENTIFIER NULL 
); 

Create Table Certifications 
(
    CertificationId UNIQUEIDENTIFIER NOT NULL PRIMARY KEY CLUSTERED, 
    EmployeeIssuedToId INT NOT NULL FOREIGN KEY REFERENCES Employees(EmployeeId), 
    ExpiryDate DATETIME2 NOT NULL 
); 

ALTER TABLE Employees 
    ADD FOREIGN KEY (CertificationId) 
     REFERENCES Certifications(CertificationId); 

В базе данных вы можете иметь сотрудников, которые могут или может не иметь сертификации, но у каждой сертификации есть соответствующий сотрудник. У меня есть следующие классы EF:

public partial class Certification 
    { 
     [Key] 
     public Guid CertificationId { get; set; } 

     public int EmployeeIssuedToId { get; set; } 
     [Required, ForeignKey("EmployeeIssuedToId")] 
     public virtual Employee EmployeeIssuedTo { get; set; } 

     [Column(TypeName = "datetime2")] 
     public DateTime ExpiryDate { get; set; } 
    } 

    public partial class Employee 
    { 
     [Key] 
     [DatabaseGenerated(DatabaseGeneratedOption.None)] 
     public int EmployeeId { get; set; } 

     [Required] 
     [StringLength(20)] 
     public string Name { get; set; } 

     public Guid? CertificationId { get; set; } 
     [ForeignKey("CertificationId")] 
     public virtual Certification Certification { get; set; } 
    } 

    public partial class EmployeeCertificationModel : DbContext 
    { 
     public EmployeeCertificationModel() 
      : base("name=DbConnString") 
     { 
     } 

     public virtual DbSet<Certification> Certifications { get; set; } 
     public virtual DbSet<Employee> Employees { get; set; } 

     protected override void OnModelCreating(DbModelBuilder modelBuilder) 
     { 
      modelBuilder.Entity<Employee>() 
       .HasOptional(e => e.Certification) 
       .WithOptionalDependent(c => c.EmployeeIssuedTo); 
     } 
    } 

Затем я пытаюсь выполнить следующий код:

 using (var writeContext = new EmployeeCertificationModel()) 
     { 
      var fred = new Employee 
      { 
       EmployeeId = 1, 
       Name = "Fred" 
      }; 
      writeContext.Employees.Add(fred); 
      writeContext.SaveChanges(); 

      fred.Certification = new Certification 
      { 
       CertificationId = new Guid("00000000-0000-0000-0000-000000000001"), 
       EmployeeIssuedToId = fred.EmployeeId, 
       ExpiryDate = DateTime.Today.AddDays(7) 
      }; 
      writeContext.SaveChanges(); 
     } 

Однако, что приводит к следующей ошибке:

System.InvalidOperationException : The ForeignKeyAttribute on property 'EmployeeIssuedTo' on type 'EmployeeCertifications.Certification' is not valid. The foreign key name 'EmployeeIssuedToId' was not found on the dependent type 'EmployeeCertifications.Employee'. The Name value should be a comma separated list of foreign key property names.

Что я делаю Неправильно здесь?

+1

Вместо 'ForeignKey ("EmployeeIssuedToId")' попробовать 'ForeignKey ("EmployeeID")' – yadejo

+0

По предложению @ yadejo, я получаю это исключение: 'Employee_Certification_Target_Employee_Certification_Source:: Типы всех свойств в зависимой роли референтное ограничение должно быть таким же, как соответствующие типы свойств в главной роли. Тип свойства «EmployeeId» в сущности «Сотрудник» не соответствует типу свойства «CertificationId» в сущности «Сертификация» в ссылочном ограничении «Employee_Certification». ' –

ответ

1

Я бы рекомендовал избегать этой ненормированной схемы в первую очередь. Таким образом, ваша первая декларация таблицы становится:

Create Table Employees 
(
    EmployeeId INT NOT NULL PRIMARY KEY, 
    Name NVARCHAR(20) NOT NULL 
); 

И вы можете определить свойство в модели с атрибутом InverseProperty.

public partial class Employee 
{ 
    ... 

    [InverseProperty("EmployeeIssuedToId")] 
    public virtual Certification Certification { get; set; } 
}