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)和试错,我得到它的工作了。