使用:EF 4.3.1时,Visual Studio 2010,SQL CE 4.0
我的理解是,在EF DataAnnotation声明外键时,它可以做到以下任一方式:
选项1-
[ForeignKey("Player1Home")]
public long? HPlayer1Id { get; set; }
public virtual Player Player1Home { get; set; }
选项2 -
public long? HPlayer1Id { get; set; }
[ForeignKey("HPlayer1Id")]
public virtual Player Player1Home { get; set; }
问题:
当InverseProperty DataAnnotation获取与方案2中使用的额外的列被在除了HPlayer1Id 数据库 (Player1Home_Id) 生成 。[Table("Matches")]
public class Match
{
[Key]
public long Id { get; set; }
//-- Option 1 - THIS WORKS GREAT --//
public long? HPlayer1Id { get; set; }
[ForeignKey("HPlayer1Id")]
public virtual Player Player1Home { get; set; }
//-- Option 2 - THIS DOES NOT WORK, it generates an extra column in the database --//
[ForeignKey("Player1Home")]
public long? HPlayer1Id { get; set; }
public virtual Player Player1Home { get; set; }
}
[Table("Players")]
public class Player
{
[Key]
public long Id { get; set; }
[InverseProperty("Player1Home")]
public virtual ICollection<Match> MatchesAsHome1 { get; set; }
}
当然,如果我重新正确命名HPlayer1Id到Player1HomeId,然后选择2级的作品。 但DataAnnotation的整个目的是允许显式的命名时,“公约”不能自动确定匹配性质。
在Player类删除InverseProperty DataAnnotation也似乎解决这个问题,但不幸的是,我不能这样做,因为我的实际匹配类中有四名球员,因此我需要明确的映射。
最后,我知道我可以只使用选项1,但我更喜欢的ID字段,而不是导航属性外键声明所有我的钥匙(主键和外)的一致性。 而在技术上,无论哪种方式应该工作。
这是刚刚在4.3.1中的错误? 在EF代码第一?
或者映射一个ForeignKey,并从两个不同的属性,以一个共同的第三个属性的InverseProperty不支持?
任何信息将不胜感激!
更新:第二个错误吗?
第三个选项应该工作以及(由Slauma的建议),但导致引发我第一次尝试将实体添加到数据库中一个NullReferenceException。 该数据库从来没有最终得到创建,而方案2从上面没有这个问题。 看来这对Slauma工作的EF 4.1,但不为我用EF 4.3.1。 (我使用它与SQL CE 4.0)[Table("Matches")]
public class Match
{
[Key]
public long Id { get; set; }
[ForeignKey("Player1Home")]
public long? HPlayer1Id { get; set; }
[InverseProperty("MatchesAsHome1")]
public virtual Player Player1Home { get; set; }
}
[Table("Players")]
public class Player
{
[Key]
public long Id { get; set; }
public virtual ICollection<Match> MatchesAsHome1 { get; set; }
}
public class MyContext : DbContext
{
public DbSet<Match> Matches { get; set; }
public DbSet<Player> Players { get; set; }
}
用法:
try
{
MyContext mc = new MyContext();
//NullReferenceException gets thrown on the next call
mc.Matches.Add(new Match());
mc.SaveChanges();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}