我目前有2個模型需要運行遷移到一個新的數據庫,而且我沒有得到我期望的結構。我很抱歉,如果這是一個簡單的答案,我對Code First with Entity Framework相當陌生。代碼首先遷移不應該存在的外鍵
首先我有一個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; }
}
基於關閉的這一點,我會希望有User
和Event
表的數據庫結構,在dbo.Event
到User
表的外鍵列(外鍵HostUserID),以及一個查找表將用戶列表映射到事件(用於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);
}
最後兩行是我要重點
.ForeignKey("dbo.Event", t => t.Event_EventID)
.Index(t => t.Event_EventID);
這是建立在用戶表事件表一個ForeignKey的那些,即使我沒有Event_EventID定義做用戶模型的任何位置。我認爲Migration假設用戶一次只能註冊1個事件,因爲我沒有看到任何查找表來確定哪些用戶註冊了哪些事件。
我試過把我的Event
模型搞亂,把ForeignKey屬性直接放在RegisteredUsers
對象上,發現這個錯誤非常快。
我該如何強制EF認識到我需要一個多對多的用戶關係事件關係?或者我是否認爲這是問題而吠叫錯誤的樹?
EDIT
我除去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; }
}
和我結束了
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 2 我經歷了,並得到我的模型到最基礎的信息,我可以使用。
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表,它只是增加了一列的數據庫,它允許單個用戶名
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);
}
我想這隻能創建一個關係是多對多的,和我結束了同樣的問題,除了現在我還有一個User_UserID列在數據庫中,每個事件只允許1個用戶。我將把我的代碼放在Edit –