Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 存储包含多个相同项的集合_C#_Sql_Sql Server_Entity Framework - Fatal编程技术网

C# 存储包含多个相同项的集合

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

我正在使用EF将数据存储到SQL Server数据库中

有两种类型的数据:

  • 形象
  • 象征
  • 每个符号都包含一组图像

    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."); }
    }