使用实体框架添加具有新导航属性的新实体

时间:2013-11-05 03:35:53

标签: c# .net entity-framework

我有一个类模型允许我将一个特征Image添加到ProductType实体。单个ProductType类定义标识引用特定Image的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属性,该属性已成功填充了包含图像的byte []信息的ImageData实例。每个实体都是新的,Id为0。

    public static Image AddImage(Image image)
    {
        Image ret = null;
        using(Context ctx = new Context())
        {
            Image ret = ctx.Images.Add(image);
            ctx.SaveChanges();
        }
        return ret;
    }

我原本预料到,由于已将一个ImageData实例分配给Navigation属性,ADD将管理两者之间的关系,插入它们并按需要更新Keys。至少那是我过去看到过它的方式。

它接近this post,但他指的是现有实体,我希望将它们都创建为新实体。

谁能看到我在这里缺少的东西?

更新日期11/05/2013

我已经将代码缩减为更少的行,以期有望缩小对该问题的关注...... 我仍然收到错误。

        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();
        }

2 个答案:

答案 0 :(得分:0)

您可能需要尝试使用Association而不是ForeignKey引用:

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

我过去曾使用过这个来为RIA服务创建自定义实体

答案 1 :(得分: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;
}
相关问题