2013-11-05 116 views
1

我有一個類模型允許我將一個要素圖像添加到ProductType實體。單獨的ProductType類定義標識引用特定圖像的HomePageImageId和HomePageImage導航屬性。使用實體框架添加具有新導航屬性的新實體

我有一個Image類定義,其中包含圖像的所有META信息(即寬度,高度,格式類型,名稱等)。

我也有一個ImageData類的定義,其中包含實際的圖像數據。這與前面提到的Image類提供的元信息具有FK關係。

所以這裏是EF實體的外觀。

[DataContract] 
[Table("ProductTypes")] 
public class ProductType : IEntity 
{ 
    [Key] 
    [DataMember] 
    [Column("Id")] 
    public Int64 Id { get; set; } 

    [DataMember] 
    [DataType(DataType.Text)] 
    [Column("Name")] 
    public String Name { get; set; } 

    [DataMember] 
    [DataType(DataType.MultilineText)] 
    [Column("Description")] 
    public String Description { get; set; } 

    [DataMember] 
    [DataType(DataType.MultilineText)] 
    [Column("Excerpt")] 
    public String Excerpt { get; set; } 

    [DataMember] 
    [Column("ImageId")] 
    public Int64? ImageId { get; set; } 

    [ForeignKey("ImageId")] 
    public virtual Image HomePageImage { get; set; } 

} 


[DataContract] 
[Table("Images")] 
public class Image : IEntity 
{ 
    [Key] 
    [DataMember] 
    [Column("Id")] 
    public Int64 Id { get; set; } 

    [DataMember] 
    [Column("Name")] 
    [DataType(DataType.Text)] 
    public String Name { get; set; } 

    // Addt'l properties removed 

    [DataMember] 
    [Column("DataId")] 
    public Int64 DataId { get; set; } 


    #region Navigation Properties 

    [ForeignKey("DataId")] 
    public virtual ImageData ImageData { get; set; } 

    #endregion 

} 


[DataContract] 
[Table("ImageData")] 
public class ImageData : IEntity 
{ 
    [Key, ForeignKey("Image")] 
    [DataMember] 
    [Column("Id")] 
    public Int64 Id { get; set; } 

    [Column("Data")] 
    [MaxLength] 
    [DataType(DataType.Upload)] 
    public byte[] Data { get; set; } 

    public virtual Image Image { get; set; } 

} 

在結構上,這一切看起來不錯。問題是,當我想添加一個新的圖像時,我收到以下錯誤。

A foreign key value cannot be inserted because a corresponding primary key value does not exist. [ Foreign key constraint name = ImageData ] 

我明白錯誤。我只是不確定它爲什麼會發生。存儲庫中的AddImage方法看起來像下面的代碼片段,其中「image」參數不僅包含Image元數據,還包含ImageData屬性,該屬性已成功填充ImageData實例,其中包含圖像的byte []信息。每個實體是新的,具有0

​​

我本來期望的是,由於的ImageData的一個實例已經被分配到導航的特性,即ADD將管理兩者之間的關係,將它們插入和更新的Id鑰匙作爲必要條件。至少我以前是這麼看待它的。

它接近this post但他指的是一個現有的實體,我正在尋找創建兩個新的實體。

任何人都可以看到我在這裏失蹤?

UPDATE 2013年11月5日

我都凝結的代碼行數更少希望縮小在這個問題上的焦點... 我仍然收到錯誤。

 using (Context ctx = new Context()) 
     { 
      // 
      // Initialize a ProductType instance. 
      ProductType productType = ProductRepository2.GetProductType(ctx, productTypeId); 
      productType.Description = txtDescription.Text.Trim(); 
      productType.Excerpt = txtDescription.Text.Substring(0, (txtDescription.Text.Trim().Length < 100) ? txtDescription.Text.Trim().Length : 100); 

      // 
      // If an image was uploaded then initialize the Image DTOs 
      if (fileUpload.FileBytes.Length > 0) 
      { 
       ImageData imgData = new ImageData { Data = fileUpload.FileBytes }; 
       productType.HomePageImage = Infrastructure.Utils.ImageUtils.GetPostedImage(fileUpload.PostedFile); 
       productType.HomePageImage.ImageData = imgData; 
       productType.HomePageImage.DateAdded = DateTime.Now; 
       productType.HomePageImage.DateUpdated = DateTime.Now; 
      } 
      ctx.SaveChanges(); 
     } 
+0

「Image」和「ImageData」之間是一對一的關係嗎?如果'ImageData'將其Id設置爲0,那麼EF可能無法按照您的預期修復它?畢竟,它是具有數據庫生成密鑰的Image實體,ImageData需要將其作爲外鍵。 – Colin

回答

0

您可能需要使用關聯嘗試,而不是一個ForeignKey參考:

[Association("FK_MyName", "ImageId", "ImageId")] 

我已經在過去使用該應用程序創建RIA服務

0

我所做的自定義實體這裏是我創建一個ProductTpe對象,並將Image對象分配給ProductType對象中的HomePageImage屬性,並且當ProductType對象添加到上下文中的ProductTypes並調用saveChanges()方法時,它將在DB中創建ImageData,Image和ProductType。

ProductType prodObj = new ProductType 
{ 
    Name="name", 
    Description= "description", 
    Excerpt ="excerpt", 
    Image= new Image //you can directly assign your image object here 
    { 
     Name="name", 
     ImageData=new ImageData 
     { 
      Data=new byte[0]; //use your data 
     } 
    } 
}; 

using(Context ctx = new Context()) 
{ 
    ctx.ProductTypes.add(prodObj); 
    ctx.saveChanges(); 
    return prodObj; 
}