3

我正在使用Entity Framwwork和Code First,並且變得非常困惑。我有這個類:實體框架與`虛擬'混淆

public class Blocks 
{ 
    [Display(Name = "ID"),Required(ErrorMessage = "ID is required")] 
    [Key,HiddenInput(DisplayValue=false)] 
    public int BlockId { get;set; } 

    [Display(Name = "Blocked By"),Required(ErrorMessage = "Blocked By is required")] 
    public int ProfileId { get;set; } 

    [Display(Name = "Blocked"),Required(ErrorMessage = "Blocked is required")] 
    public int ProfileBlockedId { get;set; } 

    [Display(Name = "Date Blocked"),Required(ErrorMessage = "Date Blocked is required")] 
    public DateTime BlockDateTime { get;set; } 

    [Display(Name = "Block Reason")] public string BlockReason { get;set; } 

    public virtual Profiles Profile { get; set; } 
    public virtual Profiles ProfileBlocked { get; set; } 
} 

配置文件類或多或少相同,並且增加了罰款和具有正確的SQL,但是當我運行/塊我得到這個錯誤:

MySql.Data.MySqlClient.MySqlException (0x80004005): Unknown column 'Extent1.Profile_ProfileId' in 'field list' 
    at MySql.Data.MySqlClient.MySqlStream.ReadPacket() 
    at MySql.Data.MySqlClient.NativeDriver.GetResult(Int32& affectedRow, Int32& insertedId) 
    at MySql.Data.MySqlClient.Driver.GetResult(Int32 statementId, Int32& affectedRows, Int32& insertedId) 
    at MySql.Data.MySqlClient.Driver.NextResult(Int32 statementId) 
    at MySql.Data.MySqlClient.MySqlDataReader.NextResult() 
    at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior) 
    at MySql.Data.Entity.EFMySqlCommand.ExecuteDbDataReader(CommandBehavior behavior) 
    at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior) 
    at System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior) 

這是因爲所產生的SQL是:

SELECT 
    `Extent1`.`BlockId`, 
    `Extent1`.`ProfileId`, 
    `Extent1`.`ProfileBlockedId`, 
    `Extent1`.`BlockDateTime`, 
    `Extent1`.`BlockReason`, 
    `Extent1`.`Profile_ProfileId`, 
    `Extent1`.`ProfileBlocked_ProfileId` 
    FROM `Blocks` AS `Extent1` 

通知的Profile_ProfileBlocked_。我將它們設置爲虛擬,以便在添加或編輯時具有配置文件下拉列表,或者在列表中顯示時具有配置文件名稱。奇怪的是其他桌子。除了這個之外,一切都運行良好。

下面是創建錯誤的SQL和斷碼:

// 
    // GET: /Blocks/ 
    public ViewResult Index() 
    { 
     try { 
     return View(context.Blocks.Include(blocks => blocks.Profile).Include(blocks => blocks.ProfileBlocked).ToList()); 
     } 
     catch (Exception ex) 
     { 
      ModelState.AddModelError("",ex.Message); 
      CompileAndSendError(ex); 
      return View(context.Blocks.ToList()); 
     } 
    } 

我使用:
ASP.net MVC 3
剃刀模板
實體框架
MVC腳手架[自定義T4]

回答

3

通過在屬性上添加註釋,爲EF提供一些提示您的外鍵屬性:

... 
[ForeignKey("Profile")] 
public int ProfileId { get;set; } 
... 
[ForeignKey("ProfileBlocked")] 
public int ProfileBlockedId { get;set; } 
... 

我相信,當您有多個導航屬性引用同一個目標類時,總是有必要的。在這種情況下,約定不會檢測哪些屬性可能是外鍵 - 並且EF會創建自己的FK列名稱(Profile_和ProfileBlocked_)。並且由於數據庫中的列名稱不同,您會得到異常。

(我認爲,這個問題已經無關性是虛擬的或沒有)。

編輯

你也可以把導航性能ForeignKey屬性,指定什麼名稱FK的屬性:

... 
[ForeignKey("ProfileId")] 
public virtual Profiles Profile { get; set; } 
... 
[ForeignKey("ProfileBlockedId")] 
public virtual Profiles ProfileBlocked { get; set; } 
... 

這導致了相同的映射,這只是一個品味你喜歡的問題,據我所知。

+0

令人驚歎的是,我以前做過的外鍵的技巧非常出色,但從來不知道用什麼方法指向IE瀏覽器引用內部名稱或引用您引入的類的ID。是否知道是否有可能擁有一個多個鍵的配置文件?哦,非常感謝 – davethecoder 2011-06-03 22:54:01

+0

@ minus4:你對「多個鍵的一個配置文件」是什麼意思?但我有這樣的感覺,答案是否定的,這是不可能的;)或者創建一個關於這個新的問題...順便說一句:我已經附加了一個關於放置FK屬性的替代編輯。 – Slauma 2011-06-03 23:35:26

+0

mucho gracias :-) – davethecoder 2011-06-04 10:02:28

0

我面臨着同樣的問題,但我可以使用建議的ForeignKey屬性來解決它。

我已經安裝了MySQL Connector/NET 6.4.3.0。當我運行我的項目時,我得到幾乎相同的錯誤,但引用System.Data.Entity。不應該是MySql.Data.Entity嗎?

你能告訴我如何修改我的Web.config或引用來使用MySQL。

編輯

一些幫助(other post)和試錯,我得到它的工作了。