C# 存储包含多个相同项的集合
我正在使用EF将数据存储到SQL Server数据库中 有两种类型的数据:C# 存储包含多个相同项的集合,c#,sql,sql-server,entity-framework,C#,Sql,Sql Server,Entity Framework,我正在使用EF将数据存储到SQL Server数据库中 有两种类型的数据: 形象 象征 每个符号都包含一组图像 public virtual ICollection<Image> Images { get; set; } 创建关系: protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Conventions.Remove<Sys
public virtual ICollection<Image> 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);
}
解释如下:
我需要为实体框架使用包装器类,因为符号
和图像
类位于共享库中。
我不想在所有其他项目中包括EF,即使我没有在那里使用它
其他一些信息:
具有3个相同图像的符号:
添加并“搜索”图像后的集合:
将此符号添加到数据库后,请查看以下表格:
图像
表格:
和关系表:
!!标记线应该在那里3次
它是Id为50的符号
,它有3张Id为108的图像。。不止一个
这里有一个简化的项目,只需几行代码即可对其进行测试:
正如您在评论中所写,多对多关系表在两个FK键上都定义了PK,因此不可能将相同的组合放置两次。我首先要考虑的是,这种情况在你的商业模式中是否真的有可能发生。如果应该,那么一种方法就是手动声明中间表并给它人工PK(例如自动递增的int)
然后在EF中,您将有两个一对多关系(从Symbol
和从Image
到中间表,您可以调用任何类似ImagesInSymbol
的关系)。
使用这些集合不太方便,但会起作用。作为奖励,您可以稍后在此关系上设置其他属性(如DateCreated
,Status
等)
有关更多详细信息,请参见此。将一个图像放在base中,并将该图像的多个副本放在内存中有什么不对(假设您出于某种原因确实需要该图像)?更多详细信息:图像表包含所有可用图像。这些符号只是有指向包含图像的“链接”。。因此,如果有一个符号多次出现在同一个图像上,我现在无法保存它。你能告诉我们表格结构吗?最重要的是,表格包含符号和图像之间的多对多映射…更新了问题。显示你用来将图像添加到符号的代码。这是我目前的工作方式在…上我原以为EF中一定有办法,但不幸的是,我不得不手动操作。。有关如何操作的更多详细信息,请参见答案下方的链接。
[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."); }
}