简单来说,有两个table:
tblInvestment
{
InvestmentId char(10), --pk
PrimaryPerformanceId char(10)
}
tblPerformance
{
PerformanceId char(10), --pk,
InvestmentId char(10)
}
然后定义了2个实体类:
[Table("tblInvestment")]
class Investment
{
[Key]
public string InvestmentId { get; set; }
public string PrimaryPerformanceId { get; set; }
[ForeignKey("PrimaryPerformanceId")]
public virtual Performance PrimaryPerformance { get; set; }
[ForeignKey("InvestmentId")]
public virtual ICollection<Performance> Performances { get; set; }
}
[Table("tblPerformance")]
class Performance
{
[Key]
public string PerformanceId { get; set; }
public string InvestmentId { get; set; }
[ForeignKey("InvestmentId")]
public virtual Investment Investment { get; set; }
}
经测试,实体类没有问题,但是当调用DbContext的时候,会出现异常:“Unable to determine a valid ordering for dependent operations. Dependencies may exist due to foreign key constraints, model requirements, or store-generated values.”
System.Data.Mapping.Update.Internal.UpdateTranslator.DependencyOrderingError(IEnumerable`1 remainder) System.Data.Mapping.Update.Internal.UpdateTranslator.ProduceCommands() System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter) System.Data.EntityClient.EntityAdapter.Update(IEntityStateManager entityCache) System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options) System.Data.Entity.Internal.InternalContext.SaveChanges() System.Data.Entity.Internal.InternalContext.SaveChanges() System.Data.Entity.Internal.LazyInternalContext.SaveChanges() System.Data.Entity.DbContext.SaveChanges()
你这里关系比较乱,是你在做测试还是项目中用到了,你的两个实体怎么会有这样的引用关系?
[ForeignKey("InvestmentId")]
public virtual ICollection<Performance> Performances { get; set; }
这里的标记也有问题吧?
当然有这样的关系。比如说一个物品拍卖,可以有很多出价记录,但是只有一个竞标成功。
这个看着有点晕,还是用FluentAPI定义看起来直观。
建议根据你的实体配置,让EF生成数据库看看。
这里有个blog:http://weblogs.asp.net/manavi/archive/2011/05/17/associations-in-ef-4-1-code-first-part-6-many-valued-associations.aspx,里面的例子跟我的有点类似:Item & Bid。
@FMax: 能不能把与这个问题相关的代码发给我?
这种多个关系可以存在,但是你的 DataAnnotation 写得确实有问题,您原来的是这样的:
[Table("tblInvestment")] public class Investment { [Key] public string InvestmentId { get; set; } public string PrimaryPerformanceId { get; set; } [ForeignKey("PrimaryPerformanceId")] public virtual Performance PrimaryPerformance { get; set; } [ForeignKey("InvestmentId")]//(1) public virtual ICollection<Performance> Performances { get; set; } } [Table("tblPerformance")] public class Performance { [Key] public string PerformanceId { get; set; } public string InvestmentId { get; set; } [ForeignKey("InvestmentId")]//(2) public virtual Investment Investment { get; set; } }
(1)和(2)应该描述的同一个外键,所以有点多余了,导致错误。
应该去掉其中一处,但是如果单纯去掉其中一处,EF还是会给tblPerformance生成两个外键,幸好EF提供了InverseProperty, 用以指定这种关系的另一端, 所以代码可以改成这样:
[Table("tblInvestment")] public class Investment { [Key] public string InvestmentId { get; set; } public string PrimaryPerformanceId { get; set; } [ForeignKey("PrimaryPerformanceId")] public virtual Performance PrimaryPerformance { get; set; } [InverseProperty("Investment")] [ForeignKey("InvestmentId")] public virtual ICollection<Performance> Performances { get; set; } } [Table("tblPerformance")] public class Performance { [Key] public string PerformanceId { get; set; } public string InvestmentId { get; set; } //[InverseProperty("Performances")] //[ForeignKey("InvestmentId")] public virtual Investment Investment { get; set; } }
或者这样:
[Table("tblInvestment")] public class Investment { [Key] public string InvestmentId { get; set; } public string PrimaryPerformanceId { get; set; } [ForeignKey("PrimaryPerformanceId")] public virtual Performance PrimaryPerformance { get; set; } //[InverseProperty("Investment")] //[ForeignKey("InvestmentId")] public virtual ICollection<Performance> Performances { get; set; } } [Table("tblPerformance")] public class Performance { [Key] public string PerformanceId { get; set; } public string InvestmentId { get; set; } [InverseProperty("Performances")] [ForeignKey("InvestmentId")] public virtual Investment Investment { get; set; } }
谢谢关注这个问题,不过问题确实不是由于这个造成的。
@FMax: Why, 您的实体类我测试过确实不行,我的测试代码是这样的:
using (var context = new BlogContext()) { context.Projects.Add(new Project { ProjectName = "TestProject", ID = Guid.NewGuid()}); context.SaveChanges(); var project = context.Projects.First(); context.ProjectUsers.Add(new ProjectUser { Project = project, UserID= "#001"}); context.SaveChanges(); }