我使用EF将数据存储到SQL Server数据库中。
有两种类型的数据:
每个符号都包含一组图像
public virtual ICollection<Image> Images { get; set; }
每个图像都包含一组符号:
public virtual ICollection<Symbol> Symbols { get; set; }
EF为多对多关系创建关系表。
如果创建(上传)了新符号,如果这些图像已经上传,程序会查看图像表。
如果是,则将添加到新符号的图像列表中。
现在有一个带有3个图像的符号(全部相同!),它将被添加到Symbols
表中。
但是在关系表中只创建了一个条目!?
所以下次从数据库中读出Symbol
时,它只包含1张图片......
我做错了什么?
或者这样做的正确方法是什么?
表格结构:
[Table("Images")]
public class SqlSymbolImgInfo
{
[Key]
public int Id { get; set; }
public String Path { get; set; }
public long Size { get; set; }
public String Md5 { get; set; }
public int X { get; set; }
public int Y { get; set; }
public virtual ICollection<SqlSymbol> Symbols { get; set; }
public override int GetHashCode()
{
return System.IO.Path.GetExtension(Path ?? "x.png").GetHashCode() + Size.GetHashCode() + (Md5 ?? "").GetHashCode();
}
}
[Table("Symbols")]
public class SqlSymbol
{
[Key]
public int Id { get; set; }
public String Description { get; set; }
public int Type { get; set; }
public virtual ICollection<SqlSymbolImgInfo> Images { get; set; }
}
创建关系:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<System.Data.Entity.ModelConfiguration.Conventions.PluralizingTableNameConvention>();
modelBuilder.Entity<SqlSymbol>().HasMany(s => s.Images).WithMany(i => i.Symbols);
base.OnModelCreating(modelBuilder);
}
添加符号:
添加图像(如果不存在)
获取添加的图片
添加符号
public void AddSymbol(Symbol sym)
{
try
{
using (var db = new Db())
{
// check if images already exists or add them..
foreach (var img in sym.Images)
{
var exImg = db.FindImage(img);
if (exImg == null)
{
var newImg = db.Images.Add(img.ConvertToSqlSymbolImgInfo());
db.SaveChanges();
img.Id = newImg.Id; // get Id of new image
}
else
{
img.Id = exImg.Id; // get Id of existing image
}
}
var sqlSym = sym.ConvertToSqlSymbol();
// get the existing entries, otherwise the same image will be added again and again...
sqlSym.Images = sym.Images.Select(i => db.Images.Find(i.Id)).ToList();
db.Symbols.Add(sqlSym);
db.SaveChanges();
sym.Id = sqlSym;
}
}
catch { logIt("error while adding a symbol."); }
}
解释:
我需要为实体框架使用包装类,Symbol
和Image
类的原因在共享库中。
而且我不想将EF包含在所有其他项目中,即使我不在那里使用它。
一些额外的信息:
带有3张相同图像的符号:
添加后的收集和&#34;搜索&#34;图像:
将此Symbol
添加到数据库后,请查看表格:
Images
表:
和关系表:
!!标记的行应该有3次?!
标识为50的Symbol
,其中有Images
,其中包含Id 108 ..不只是一个!
这是一个简单的项目,只需几行代码即可对其进行测试:
答案 0 :(得分:1)
正如您在评论中所写,多对多关系表在两个FK键上都定义了PK,因此不可能将两次相同的组合放在一起。我首先考虑一下你的商业模式是否真的可以实现这种情况。如果它应该,那么你可以采用的一种方法是手动声明你的中间表并给它人工PK(例如,只是自动增加int)。
然后在EF中,您将拥有两个一对多关系(从Symbol
和从Image
到中级表,您可以调用任何内容 - 例如ImagesInSymbol
左右。
使用这些集合将不太方便但可行。作为奖励,您稍后可以在此关系上设置其他属性(例如DateCreated
,Status
等)。
有关详细信息,请参阅此question。