问题描述
我有一个类模型允许我向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;组;
[DataMember]
[DataType(DataType.Text)]
[Column(Name)]
public String Name {get;组; }
[DataMember]
[DataType(DataType.MultilineText)]
[Column(Description)]
public String描述{get;组;
[DataMember]
[DataType(DataType.MultilineText)]
[Column(Excerpt)]
public String摘录{get;组;
[DataMember]
[Column(ImageId)]
public Int64? ImageId {get;组; }
[ForeignKey(ImageId)]
public virtual Image HomePageImage {get;组;
}
[DataContract]
[Table(Images)]
public class Image:IEntity
{
[Key]
[DataMember]
[Column(Id)]
public Int64 Id {get;组;
[DataMember]
[Column(Name)]
[DataType(DataType.Text)]
public String Name {get;组;
//删除了Addt'l属性
[DataMember]
[Column(DataId)]
public Int64 DataId {get;组;
#region导航属性
[ForeignKey(DataId)]
public virtual ImageData ImageData {get;组;
#endregion
}
[DataContract]
[Table(ImageData)]
public class ImageData:IEntity
{
[Key,ForeignKey(Image)]
[DataMember]
[Column(Id)]
public Int64 Id {get;组; }
[Column(Data)]
[MaxLength]
[DataType(DataType.Upload)]
public byte [] Data {get;组; }
public virtual Image Image {get;组; }
}
结构上这一切都看起来不错。问题是当我想添加一个新的图像时,我收到以下错误。
无法插入外键值,因为相应的主键值不存在。 [外键约束名称= ImageData]
我明白错误。我只是不知道为什么会发生。存储库中的AddImage方法看起来像以下代码片段,其中image参数不仅包含Image元数据,而且还包含ImageData属性,该属性已成功填充包含图像的byte []信息的ImageData实例。每个实体都是新的,并且ID为0.
public static Image AddImage(Image image)
{
Image ret = null;
使用(Context ctx = new Context())
{
Image ret = ctx.Images.Add(image);
ctx.SaveChanges();
}
return ret;
}
我预计由于ImageData的一个实例已被分配到导航ADD将管理两者之间的关系,插入它们并将密钥更新为重要的属性。至少这是我以前看到它的工作。
它接近于,但是他指的是一个现有的实体,我正在寻找创建两个新的实体。
任何人都可以看到什么我错过了这里?
更新11/05/2013
我有将代码缩小到更少的行数,希望能够缩小焦点的问题...
我仍然收到错误。
using(Context ctx = new Context())
{
//
//初始化一个ProductType实例。
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);
//
//如果图像被上传,则初始化图像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();
}
创建一个ProductTpe对象,并将Image对象分配给ProductType对象中的HomePageImage属性,当我在上下文中将ProductType对象添加到ProductTypes并调用saveChanges()方法时,将在DB中创建ImageData,Image和ProductType。
ProductType prodObj = new ProductType
{
Name =name,
描述=description,
Excerpt =excerpt,
Image = new Image //您可以在这里直接分配您的图像对象
{
Name =name,
ImageData = new ImageData
{
数据=新字节[0]; //使用你的数据
}
}
};
using(Context ctx = new Context())
{
ctx.ProductTypes.add(prodObj);
ctx.saveChanges();
return prodObj;
}
I have a class model allows me to add a feature Image to a ProductType entity. The individual ProductType class definition identifies a HomePageImageId and HomePageImage navigation property which references a specific Image.
I have an Image class definition which contains all the META information for an image (i.e. width, height, format type, name, etc.).
I also have an ImageData class definition which contains the actual image data. This possesses a FK relationship to it's meta information available via the aforementioned Image class.
So here's what the EF Entities look like.
[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; }
}
Structurally this all looks good. The problem is that when I want to ADD a new image I am getting the following error.
A foreign key value cannot be inserted because a corresponding primary key value does not exist. [ Foreign key constraint name = ImageData ]
I understand the error. I am just not sure why it's occurring. The AddImage method in the repository looks like the following code snippet where the "image" parameter contains not only the Image meta data, but its ImageData property which has been successfully populated with an instance of ImageData containing the byte[] information for an image. Each entity is new and have Id's of 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;
}
I would have expected that since an instance of ImageData has been assigned to the Navigation property that the ADD would manage the relationships between the two, inserting them and updating the Keys as neeccessary. At least that's how I have seen it work in the past.
It's close to this post but where he is referring to an existing entity I am looking to create both as new entities.
Can anyone see what I am missing here?
UPDATE 11/05/2013
I have condensed the code to fewer lines to hopefully narrow the spotlight on the issue ...I am still receiving the error.
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();
}
What I do here is I create a ProductTpe object and assign Image object to HomePageImage property in ProductType object and when I add ProductType object to ProductTypes in context and call saveChanges() method, It will create ImageData, Image and ProductType in DB.
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;
}
这篇关于使用实体框架添加具有新导航属性的新实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!