2017-02-27 3 views
1

현재 새 데이터베이스로 마이 그 레이션을 실행해야하는 모델이 2 개 있으며 예상 한 구조를 얻지 못하고 있습니다. 이것이 쉬운 대답이라면 사과드립니다. Entity Framework의 Code First를 처음 접해 보았습니다.코드에 외래 키가 있어야합니다. 처음에는 이동하지 않아야합니다.

먼저 User 개체가 있습니다. 이건 그냥 기본 키에 대한 UserID을해야하고 일부 필드는 기입 할 수 있습니다.

public class User : CustomDataEntity 
{ 
    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public int UserID { get; set; } 
    public string Username { get; set; } 
    public string Password { get; set; } 
    public DateTime Birthday { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string EmailAddress { get; set; } 
    public byte[] Picture { get; set; } 
} 

을 그리고, 나는 Event 개체가 있습니다. 이 기본 키로 EventID 있어야하며 ForeignKey'd HostUser뿐만 아니라 RegisteredUsers 테이블에 저장된 이벤트에 대해 등록 된 사용자 목록을 가지고 노력하고있어. 이를 기반으로

public class Event : CustomDataEntity 
{ 
    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public int EventID { get; set; } 
    [ForeignKey("HostUser")] 
    public int HostUserID { get; set; } 
    [ForeignKey("RegisteredUsers")] 
    public ICollection<int> RegisteredUserIDs { get; set; } 
    public virtual User HostUser { get; set; } 
    public string Description { get; set; } 
    public virtual ICollection<User> RegisteredUsers { get; set; } 
} 

, 나는 (외국 키가 HostUserID 용) User 테이블 dbo.Event에서 외국 키가 열 및 룩업 테이블, UserEvent 테이블과 데이터베이스 구조를 기대하는 사용자 목록을 이벤트에 매핑합니다 (RegisteredUsers 목록 용).

이 구조체를 기반으로 마이그레이션을 만들면 Up() 부분에 대해 다음 CreateTable 메서드가 생성됩니다.

public override void Up() 
    { 
     CreateTable(
      "dbo.Event", 
      c => new 
       { 
        EventID = c.Int(nullable: false, identity: true), 
        HostUserID = c.Int(nullable: false), 
        Description = c.String(nullable: false), 
        NumberOfUsers = c.Int(nullable: false), 
        StartDate = c.DateTime(nullable: false), 
        EndDate = c.DateTime(), 
        CreatedAt = c.DateTimeOffset(precision: 7, 
         annotations: new Dictionary<string, AnnotationValues> 
         { 
          { 
           "ServiceTableColumn", 
           new AnnotationValues(oldValue: null, newValue: "CreatedAt") 
          }, 
         }), 
        Deleted = c.Boolean(nullable: false, 
         annotations: new Dictionary<string, AnnotationValues> 
         { 
          { 
           "ServiceTableColumn", 
           new AnnotationValues(oldValue: null, newValue: "Deleted") 
          }, 
         }), 
        Id = c.String(
         annotations: new Dictionary<string, AnnotationValues> 
         { 
          { 
           "ServiceTableColumn", 
           new AnnotationValues(oldValue: null, newValue: "Id") 
          }, 
         }), 
        UpdatedAt = c.DateTimeOffset(precision: 7, 
         annotations: new Dictionary<string, AnnotationValues> 
         { 
          { 
           "ServiceTableColumn", 
           new AnnotationValues(oldValue: null, newValue: "UpdatedAt") 
          }, 
         }), 
        Version = c.Binary(
         annotations: new Dictionary<string, AnnotationValues> 
         { 
          { 
           "ServiceTableColumn", 
           new AnnotationValues(oldValue: null, newValue: "Version") 
          }, 
         }), 
       }) 
      .PrimaryKey(t => t.EventID) 
      .ForeignKey("dbo.User", t => t.HostUserID, cascadeDelete: true) 
      .Index(t => t.HostUserID); 

     CreateTable(
      "dbo.User", 
      c => new 
       { 
        UserID = c.Int(nullable: false, identity: true), 
        Username = c.String(nullable: false), 
        Password = c.String(nullable: false), 
        Birthday = c.DateTime(nullable: false), 
        FirstName = c.String(nullable: false), 
        LastName = c.String(nullable: false), 
        EmailAddress = c.String(nullable: false), 
        Picture = c.Binary(), 
        CreatedAt = c.DateTimeOffset(precision: 7, 
         annotations: new Dictionary<string, AnnotationValues> 
         { 
          { 
           "ServiceTableColumn", 
           new AnnotationValues(oldValue: null, newValue: "CreatedAt") 
          }, 
         }), 
        Deleted = c.Boolean(nullable: false, 
         annotations: new Dictionary<string, AnnotationValues> 
         { 
          { 
           "ServiceTableColumn", 
           new AnnotationValues(oldValue: null, newValue: "Deleted") 
          }, 
         }), 
        Id = c.String(
         annotations: new Dictionary<string, AnnotationValues> 
         { 
          { 
           "ServiceTableColumn", 
           new AnnotationValues(oldValue: null, newValue: "Id") 
          }, 
         }), 
        UpdatedAt = c.DateTimeOffset(precision: 7, 
         annotations: new Dictionary<string, AnnotationValues> 
         { 
          { 
           "ServiceTableColumn", 
           new AnnotationValues(oldValue: null, newValue: "UpdatedAt") 
          }, 
         }), 
        Version = c.Binary(
         annotations: new Dictionary<string, AnnotationValues> 
         { 
          { 
           "ServiceTableColumn", 
           new AnnotationValues(oldValue: null, newValue: "Version") 
          }, 
         }), 
        Event_EventID = c.Int(), 
       }) 
      .PrimaryKey(t => t.UserID) 
      .ForeignKey("dbo.Event", t => t.Event_EventID) 
      .Index(t => t.Event_EventID); 

    } 

마지막 두 줄을 내가 Event_EventID 정의하지 않더라도, 나는

.ForeignKey("dbo.Event", t => t.Event_EventID) 
.Index(t => t.Event_EventID); 

이는 이벤트 테이블에 사용자 테이블에 외래 키를 만드는에 초점을 맞출 것입니다 사용자 모델 어디에서나 사용할 수 있습니다. 나는 어떤 사용자가 어떤 이벤트에 등록되어 있는지 파악할 수있는 조회 테이블을 보지 못하기 때문에 사용자가 한 번에 하나의 이벤트 만 등록 할 것으로 가정하고있다.

RegisteredUsers 개체에 ForeignKey 속성을 직접 넣어서 내 Event 모델을 망쳐 놓으려고했지만 꽤 빠름을 알았습니다.

사용자 간 이벤트를 위해 다 대 다 관계가 필요하다는 것을 EF가 인식하도록하려면 어떻게해야합니까? 아니면 문제가 있다고 가정하여 잘못된 트리를 짖고 있습니까?

편집

은 내가 ForeignKey 속성과 설정을 각각 ICollection에 제거하고, 지금은 이벤트 당 단일 사용자에 대해 허용하는 추가 열을 제외하고 난 여전히 같은 오류가 있고,없고 EventUsers 테이블입니다.

public class User : CustomDataEntity 
{ 
    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public int UserID { get; set; } 
    public string Username { get; set; } 
    public string Password { get; set; } 
    public DateTime Birthday { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string EmailAddress { get; set; } 
    public byte[] Picture { get; set; } 
    public virtual ICollection<Event> EventsRegisteredFor { get; set; } 
} 

public class Event : CustomDataEntity 
{ 
    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public int EventID { get; set; } 
    public virtual User HostUser { get; set; } 
    public string Description { get; set; } 
    public virtual ICollection<User> RegisteredUsers { get; set; } 
} 

와 나는 내가 겪은 내가 사용할 수있는 가장 기본 정보까지 내 모델을 가지고 2

 CreateTable(
      "dbo.Event", 
      c => new 
       { 
        EventID = c.Int(nullable: false, identity: true), 
        Description = c.String(nullable: false), 
        NumberOfUsers = c.Int(nullable: false), 
        StartDate = c.DateTime(nullable: false), 
        EndDate = c.DateTime(), 
        User_UserID = c.Int(), 
        HostUser_UserID = c.Int(nullable: false), 
       }) 
      .PrimaryKey(t => t.EventID) 
      .ForeignKey("dbo.User", t => t.User_UserID) 
      .ForeignKey("dbo.User", t => t.HostUser_UserID, cascadeDelete: true) 
      .Index(t => t.User_UserID) 
      .Index(t => t.HostUser_UserID); 

     CreateTable(
      "dbo.User", 
      c => new 
       { 
        UserID = c.Int(nullable: false, identity: true), 
        Username = c.String(nullable: false), 
        Password = c.String(nullable: false), 
        Birthday = c.DateTime(nullable: false), 
        FirstName = c.String(nullable: false), 
        LastName = c.String(nullable: false), 
        EmailAddress = c.String(nullable: false), 
        Picture = c.Binary(), 
        Event_EventID = c.Int(), 
       }) 
      .PrimaryKey(t => t.UserID) 
      .ForeignKey("dbo.Event", t => t.Event_EventID) 
      .Index(t => t.Event_EventID); 

EDIT로 끝날.

public class User : CustomDataEntity 
{ 
    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public int UserID { get; set; } 
    public string Username { get; set; } 
    public virtual List<Event> Events { get; set; } 
} 
public class Event : CustomDataEntity 
{ 
    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public int EventID { get; set; } 
    public virtual User HostUser { get; set; } 
    public virtual List<User> Users { get; set; } 
} 

그러나,이 구조는 여전히 나에게 필요한 EventUsers 또는 UserEvents 테이블을 제공하지 않습니다, 단순히 많은-하는 단일 사용자 ID

public override void Up() 
    { 
     CreateTable(
      "dbo.Event", 
      c => new 
       { 
        EventID = c.Int(nullable: false, identity: true), 
        User_UserID = c.Int(), 
        HostUser_UserID = c.Int(), 
       }) 
      .PrimaryKey(t => t.EventID) 
      .ForeignKey("dbo.User", t => t.User_UserID) 
      .ForeignKey("dbo.User", t => t.HostUser_UserID) 
      .Index(t => t.User_UserID) 
      .Index(t => t.HostUser_UserID); 

     CreateTable(
      "dbo.User", 
      c => new 
       { 
        UserID = c.Int(nullable: false, identity: true), 
        Username = c.String(), 
        Event_EventID = c.Int(), 
       }) 
      .PrimaryKey(t => t.UserID) 
      .ForeignKey("dbo.Event", t => t.Event_EventID) 
      .Index(t => t.Event_EventID); 

    } 

답변

0

수 있습니다 데이터베이스에 하나의 열을 추가 - 많은 관계, 그냥 각 모델에서 컬렉션을 추가 : 사용자 모델에서

추가 :

public 가상 ICollection에 이벤트 {설정; 도망; } // 많은 많은-에

및 이벤트 모델에 추가 :

public 가상 ICollection이 사용자 {설정; 도망; } // many-to-many


다른 외래 키를 사용할 필요가 없습니다.

엔티티 프레임 워크가 자동으로 EventUsers 테이블을 만들고 dbcontext에서이 테이블에 액세스 할 수 없습니다. (액세스가 필요하지 않음)

EventUsers 테이블에 액세스하려면 사용자와 이벤트에서 다 대다 관계를 삭제하고 EventUsers와 같은 새 모델을 작성하고 일대 다 관계를 만들어야합니다. 사용자를 이벤트 사용자로, 이벤트에서 이벤트 사용자로 이 두 테이블의 기본 키가 할 수있는 사용자를 의미

public class User 
{ 
    [Key] 
    public int UserID { get; set; } 
    public string Username { get; set; } 
    public List<Event> Events { get; set; } 
} 
public class Event 
{ 
    [Key] 
    public int EventID { get; set; } 
    public List<User> Users { get; set; } 
} 

user 클래스 이벤트 list 사용 주 및 event 클래스 같은 예 포함 세번째 테이블을 생성한다 대다 관계로 다수의

+0

의 필요가 없습니다 그래서 많은 많은 하나만 관계를 묶는되도록이 많은 관계로 하나를 만들어 public virtual User HostUser { get; set; } 사용, 그리고 한 이제는 이벤트 당 1 명의 사용자 만 허용하는 데이터베이스의 User_UserID 열을 제외하고 같은 문제가 발생합니다. 내 코드를 편집 –

0

많은 이벤트가 있고 이벤트에는 많은 사용자 (many to many) 이있을 수 있으므로 마이그레이션을 추가하면 두 테이블의 외래 키가 포함 된 세 번째 테이블 이름 UserEvent이 생성됩니다.

편집

당신은 내가이 시도 public virtual User HostUser { get; set; }

+0

에 넣고 [DatabaseGenerated (DatabaseGeneratedOption.Identity)]가 필요하지 않습니다. CustomDataEntity – Usman

+0

CustomDataEntity 대신 "ITableData"가 필요합니까? –

+0

아니요 dbset이 dbset에서 모델을 추가 할 때 dbcontext가 처리 할 항목이 없습니다. – Usman