2017-04-04 213 views
2

我有實體的曲線和點之間的一個一對多的關係,定義如下:如何配置包含一個外鍵複合主鍵(EF流利API)

public class Curve 
{ 
    public Curve() 
    { 
     Points = new HashSet<Point>(); 
    } 

    public int CurveId { get; set; } 

    public string Name { get; set; } 

    public virtual ICollection<Point> Points { get; set; } 
} 

和:

public class Point 
{ 
    public int Point_Num { get; set; } 

    public int CurveId { get; set; } 

    public double XCoord { get; set; } 

    public double YCoord { get; set; } 

    public virtual Curve Curve { get; set; } 
} 

以我上下文類,我配置鍵和導航性能如下(請注意,點實體具有複合主鍵):

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 

    modelBuilder.Entity<Curve>() 
     .HasKey(c => c.CurveId); 

    modelBuilder.Entity<Point>() 
     .HasKey(p => new { p.Point_Num, p.CurveId }); 

    modelBuilder.Entity<Point>() 
     .HasRequired(p => p.Curve) 
     .WithMany(c => c.Points) 
     .HasForeignKey(p => p.CurveId); 

} 

別的地方的代碼,我填充數據庫:

var curve = new Curve 
{ 
    Name = "curve 1" 
}; 

var points = new List<Point>(); 
points.Add(new Point 
{ 
    XCoord = 1d, 
    YCoord = 1d, 
}); 

points.Add(new Point 
{ 
    XCoord = 2d, 
    YCoord = 2d, 
}); 

foreach (var point in points) 
{ 
    curve.Points.Add(point); 
} 

using (var dbCtxt = new MyDbContext()) 
{ 
    try 
    { 
     dbCtxt.Curves.Add(curve); 
     dbCtxt.SaveChanges(); 
    } 
    catch (Exception e) 
    { 
     Console.WriteLine(e.StackTrace); 
    } 
} 

時調用SaveChanges()被調用,則會引發錯誤「而更新條目中出現了一個錯誤。」

如果我將Point_Num定義爲Point實體的主鍵,則所有實體都會更新。看起來問題來自於這個事實:複合主鍵(Point_Num,CurveId)包含一個外鍵(CurveId)

我無法理解這一點,這顯然是我缺少的東西。任何幫助都感激不盡!

回答

1

所以我已經做了我應該在第一時間做了,這是創造我的SQL表和使用實體數據模型嚮導生成我在C#中的實體(使用「代碼首先從數據庫」)

這樣做,我注意到,EF產生的點實體具有以下「DatabaseGeneratedOption.None」數據上的複合主鍵註釋:

public partial class Points 
{ 
    [Key] 
    [Column(Order = 0)] 
    [DatabaseGenerated(DatabaseGeneratedOption.None)] 
    public int Point_Num { get; set; } 

    [Key] 
    [Column(Order = 1)] 
    [DatabaseGenerated(DatabaseGeneratedOption.None)] 
    public int Curve_Id { get; set; } 

    ... 

    public virtual Curve Curve { get; set; } 
} 

我impelemented此使用流利API:

modelBuilder.Entity<Point>().Property(p => p.PointId) 
      .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); 

在代碼填充數據庫中的位,我創建了說,2個不同的「曲線」實體:

 var curve1 = new Curve 
     { 
      Name = "curve 1" 
     }; 

     var curve2 = new Curve 
     { 
      Name = "curve 2" 
     }; 

然後創建「點」實體指定點名和CurveId。例如。比方說,我想一個點添加到每條曲線:

var points = new List<Point>(); 

points.Add(new Point 
{ 
    PointId = 1, 
    CurveId = 1, 
    XCoord = 1.2d, 
    YCoord = 3.1d, 
}); 

points.Add(new Point 
{ 
    PointId = 1, 
    CurveId = 2, 
    XCoord = 0.5d, 
    YCoord = 0.75d, 
}); 

當添加實體的背景下,這是不夠的加入曲線1和CURVE2,我還需要添加以前創建點名單,EF不會自動上傳:

myContext.Points.AddRange(points); 
myContext.Curves.Add(curve1); 
myContext.Curves.Add(curve2); 
myContext.SaveChanges(); 

這不是一個優雅的解決方案。我希望能有這樣一種更直接的方式,但是這解決了我的問題!數據庫被正確更新,所有的密鑰和外鍵都正確設置...