2016-03-28 54 views
0

我知道這個問題已經討論了幾次,但是這個問題與內置的Identity模型有關。MVC標識 - INSERT語句與FOREIGN KEY約束衝突

我創建了一個名爲「Company」的自定義模型。註冊新用戶時,我也想選擇公司名稱。

我已經將所需的數據添加到RegisterViewModel中,並且視圖和窗體顯示應該如此。我已經在公司表中找到了2家公司,因此其值不應爲空。

public class RegisterViewModel 
{   
    ... Removed some irrelevant code ... 

    [Required(ErrorMessage = "You must select a company name.")] 
    [Display(Name = "Company")] 
    public int CompanyID { get; set; } 
    public virtual Company ApplicationUser_Company { get; set; } 

的問題出現了,當我要插入與下面的錯誤新用戶:

The INSERT statement conflicted with the FOREIGN KEY constraint "FK_dbo.AspNetUsers_dbo.Companies_CompanyID". The conflict occurred in database "aspnet-ProjectMed-20160327120257", table "dbo.Companies", column 'CompanyID'. 
The statement has been terminated. 

檢查帳戶控制我看不出任何問題:

// GET: /Account/Register 
    [AllowAnonymous] 
    public ActionResult Register() 
    { 
     ViewBag.CompanyID = new SelectList(db.Companies, "CompanyID", "Company_Name"); 
     return View(); 
    } 

    // 
    // POST: /Account/Register 
    [HttpPost] 
    [AllowAnonymous] 
    [ValidateAntiForgeryToken] 
    public async Task<ActionResult> Register(RegisterViewModel model) 
    { 
     if (ModelState.IsValid) 
     { 
      var user = new ApplicationUser { UserName = model.Email, Email = model.Email, ApplicationUser_FirstName = model.ApplicationUser_FirstName, ApplicationUser_LastName = model.ApplicationUser_LastName, ApplicationUser_Company = model.ApplicationUser_Company }; 

       var result = await UserManager.CreateAsync(user, model.Password); <<<---- This is where the error occurs <<<--- 
       if (result.Succeeded) 
       { 
        await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false); 

        return RedirectToAction("Index", "Home"); 
       } 
       AddErrors(result); 

     } 

     // If we got this far, something failed, redisplay form 
     return View(model); 
    } 

我也是複製SQL表格:

AspNetUsers表格:

CREATE TABLE [dbo].[AspNetUsers] (
    [Id]      NVARCHAR (128) NOT NULL, 
    [ApplicationUser_FirstName] NVARCHAR (50) NOT NULL, 
    [ApplicationUser_LastName] NVARCHAR (50) NOT NULL, 
    [CompanyID]     INT   NOT NULL, 
    [Email]      NVARCHAR (256) NULL, 
    [EmailConfirmed]   BIT   NOT NULL, 
    [PasswordHash]    NVARCHAR (MAX) NULL, 
    [SecurityStamp]    NVARCHAR (MAX) NULL, 
    [PhoneNumber]    NVARCHAR (MAX) NULL, 
    [PhoneNumberConfirmed]  BIT   NOT NULL, 
    [TwoFactorEnabled]   BIT   NOT NULL, 
    [LockoutEndDateUtc]   DATETIME  NULL, 
    [LockoutEnabled]   BIT   NOT NULL, 
    [AccessFailedCount]   INT   NOT NULL, 
    [UserName]     NVARCHAR (256) NOT NULL, 
    CONSTRAINT [PK_dbo.AspNetUsers] PRIMARY KEY CLUSTERED ([Id] ASC), 
    CONSTRAINT [FK_dbo.AspNetUsers_dbo.Companies_CompanyID] FOREIGN KEY ([CompanyID]) REFERENCES [dbo].[Companies] ([CompanyID]) ON DELETE CASCADE 
); 

GO 
CREATE NONCLUSTERED INDEX [IX_CompanyID] 
    ON [dbo].[AspNetUsers]([CompanyID] ASC); 

GO 
CREATE UNIQUE NONCLUSTERED INDEX [UserNameIndex] 
    ON [dbo].[AspNetUsers]([UserName] ASC); 

公司表:

CREATE TABLE [dbo].[Companies] (
    [CompanyID]   INT   IDENTITY (1, 1) NOT NULL, 
    [Company_Name]  NVARCHAR (50) NOT NULL, 
    [Company_Code]  NVARCHAR (9) NOT NULL, 
    [Company_Address1] NVARCHAR (100) NOT NULL, 
    [Company_Address2] NVARCHAR (100) NULL, 
    [Company_PostalCode] NVARCHAR (15) NOT NULL, 
    [Company_City]  NVARCHAR (50) NOT NULL, 
    [CountryID]   INT   NOT NULL, 
    [Company_CLOG]  BIT   NOT NULL, 
    [Company_SubAgent] BIT   NOT NULL, 
    CONSTRAINT [PK_dbo.Companies] PRIMARY KEY CLUSTERED ([CompanyID] ASC), 
    CONSTRAINT [FK_dbo.Companies_dbo.Countries_CountryID] FOREIGN KEY ([CountryID]) REFERENCES [dbo].[Countries] ([CountryID]) ON DELETE CASCADE 
); 


GO 
CREATE UNIQUE NONCLUSTERED INDEX [IX_Company_Code] 
    ON [dbo].[Companies]([Company_Code] ASC); 


GO 
CREATE NONCLUSTERED INDEX [IX_CountryID] 
    ON [dbo].[Companies]([CountryID] ASC); 

任何想法和這裏有什麼錯?

+0

然後model.ApplicationUser_Company值是正確的UserManager.CreateAsync過嗎? – DanielVorph

回答

0

看來我發現錯誤要感謝您的上一個建議!我嘗試設置外鍵,而不是如果ID值...

爲我工作的代碼:

[HttpPost] 
public async Task<ActionResult> Register(RegisterViewModel model) 
{ 
    // verify the models' valid 
    if (ModelState.IsValid) 
    { 
     var user = new ApplicationUser { 
     /* ... */, 
     CompanyID = model.CompanyID // entity we retrieved 
     }; 

     // 
     // SignInManager yatta yata 
     // 
    } 
    return View(model); // Uh-oh fallback. 
} 
0

的直覺告訴我,這是此行(分解爲清楚起見/解說)內:

var user = new ApplicationUser 
{ 
    UserName = model.Email, 
    Email = model.Email, 
    ApplicationUser_FirstName = model.ApplicationUser_FirstName, 
    ApplicationUser_LastName = model.ApplicationUser_LastName, 
    ApplicationUser_Company = model.ApplicationUser_Company  // <-- 
}; 

基本上,通過表單操作之間的實體引用時,要引用的ID(作爲一個整體的實體不穿越電線,也不應出於安全目的(格式錯誤的輸入,黑客入侵等))。

您的視圖模型(在這種情況下RegisterViewModel應該真的只有CompanyID(其是Company實體的PK)。這應該然後使用由執行查找,然後分配到user來填充新用戶ApplicationUseruser)。例如

[HttpPost] 
public async Task<ActionResult> Register(RegisterViewModel model) 
{ 
    // verify the models' valid 
    if (ModelState.IsValid) 
    { 
    // Perform a lookup to retrieve the selected company 
    var company = db.COmpanies.SingleOrDefault(x => x.CompanyID == model.CompanyID); 
    if (company != null) // Found it 
    { 
     // No go on to establish an application user 
     var user = new ApplicationUser { 
     /* ... */, 
     ApplicationUser_Company = company // entity we retrieved 
     }; 

     // 
     // SignInManager yatta yata 
     // 
    } 
    } 
    return View(model); // Uh-oh fallback. 
} 

不過請注意,如果您ApplicationUser實體有兩個屬性(大多數人),一個ID和一個用於對外關係;例如

public int CompanyID { get; set; } // ID property 
[ForeignKey("CompanyID")] 
public virtual Company Company { get; set; } // entity property 

您只需分配/或。在這種情況下,您不需要在填充ApplicationUser之前執行查找,並且可以簡單地設置user.CompanyID = model.CompanyID;

+0

謝謝布拉德!我已經添加了查找'var company = db.Companies ....',似乎我們更接近解決這個謎團。但是現在我得到錯誤「一個實體對象不能被多個IEntityChangeTracker實例引用」。任何建議?對不起,如果這是一個新手問題... :) – Rok

相關問題