You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用OleDB和Entity Framework插入数据时如何避免重复?

Excel导入数据库避免重复插入的实现方案

核心优化思路

  • 提前拉取数据库中已存在的唯一标识(此处以siteIDDatagate作为去重依据,你可以根据实际业务调整为其他唯一字段或组合字段),存入内存集合做校验,避免循环中每次查询数据库导致性能低下
  • 去掉循环内的单次SaveChanges(),改为批量提交,大幅提升导入效率
  • 移除无效的Attach()操作,新创建的实体对象直接执行新增操作即可,不需要提前附加到上下文

修改后的实现代码

DataView ImportarDatosSites(string filename)
{
    // 提前查询数据库中已存在的siteIDDatagate,存入HashSet做O(1)效率的校验
    HashSet<string> existSiteIds = new HashSet<string>(db.SitesMtto.Select(x => x.siteIDDatagate).ToList());

    string conexion = string.Format("Provider = Microsoft.ACE.OLEDB.12.0; Data Source={0}; Extended Properties= 'Excel 8.0;HDR=YES'" ,filename );
    using (OleDbConnection connection = new OleDbConnection(conexion))
    {
        connection.Open();
        OleDbCommand command = new OleDbCommand("SELECT * FROM [BaseSitiosTelemetria$]", connection);
        OleDbDataAdapter adaptador = new OleDbDataAdapter { SelectCommand = command };
        DataSet ds = new DataSet();
        adaptador.Fill(ds);
        DataTable dt = ds.Tables[0];
  
        using (OleDbDataReader dr = command.ExecuteReader())
        {
            while (dr.Read())
            {
                var SiteID     = dr[1];
                var currentSiteId = SiteID.ToString();
                // 校验ID是否已存在,存在直接跳过
                if (existSiteIds.Contains(currentSiteId))
                {
                    continue;
                }

                var ID_AA_FB   = dr[2];
                var Address    = dr[3];
                var CreateDate = dr[5];
                var Tipo       = dr[7];
                var Measures   = dr[9];
                var Latitud    = dr[10];
                var Longitud   = dr[11];

                SitesMtto s = new SitesMtto();
                s.siteIDDatagate      = currentSiteId;
                s.idFieldBeat         = ID_AA_FB.ToString();
                s.addressDatagate     = Address.ToString();
                s.createDateDatagate  = Convert.ToDateTime(CreateDate);
                s.typeDevice          = Tipo.ToString();
                s.MeasuresDevice      = Measures.ToString();
                if (Latitud.ToString() != "" && Longitud.ToString() != "")
                {
                    s.latitudeSite  = Convert.ToDouble(Latitud);
                    s.longitudeSite = Convert.ToDouble(Longitud);
                }

                db.SitesMtto.Add(s);
                // 把新增的ID也加入校验集合,避免Excel内本身有重复ID的情况
                existSiteIds.Add(currentSiteId);
            }
            // 批量提交所有新增操作,大幅提升性能
            db.SaveChanges();
            connection.Close();
            return ds.Tables[0].DefaultView;
        }
    }
}

扩展:如果需要实现「存在则更新、不存在则插入」的逻辑

只需要修改校验部分的代码即可:

// 替换之前的ID校验逻辑
var existSite = db.SitesMtto.FirstOrDefault(x => x.siteIDDatagate == currentSiteId);
if (existSite != null)
{
    // 给已存在的实体赋新值
    existSite.idFieldBeat = ID_AA_FB.ToString();
    existSite.addressDatagate = Address.ToString();
    // 其他需要更新的字段依次赋值
}
else
{
    // 新增实体逻辑和之前一致
    SitesMtto s = new SitesMtto();
    // 赋值属性
    db.SitesMtto.Add(s);
}

内容的提问来源于stack exchange,提问作者Enrico Grez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 15:54:01