【问题标题】:C# Linq "Entity with the same key '0' already added." when inserting multiple rowsC# Linq“已添加具有相同键 '0' 的实体。”插入多行时
【发布时间】:2013-08-07 14:25:45
【问题描述】:

我正在尝试批量插入数据,数据库是 MySQL 连接是使用 Devart LinqConnect 完成的。 这是一个代码:

DataContext db = new DataContext();
List<XYData> XYDList = new List<XYData>(); // Data Type
List<xydata> xyToBeInsrted = new List<xydata>(); // Database table

XYDList = XYData.genXYData(12, 1234); // Generates 12 example records 

foreach (XYData oneXY in XYDList)
{
    // Create clear row representation               
    xydata xy_row = new xydata();
    // Assign data from object
    xy_row.id = oneXY.Id;
    xy_row.Batchid = (int)oneXY.BatchId;
    xy_row.Ch = oneXY.Channel;
    xy_row.Value = oneXY.Value;
    xy_row.Pos = (int)oneXY.Position;
    xy_row.Dtm = oneXY.Time;

    // Add to list of rows to be inserted
    xyToBeInsrted.Add(xy_row);

}
db.xydatas.InsertAllOnSubmit<xydata>(xyToBeInsrted);
db.SubmitChanges();

最后一行给出错误“已添加具有相同键 '0' 的实体”。 当我将要生成的项目数减少到 1 时,它会起作用。任何高于 1 的值都会出错。

表已在记录 ID 字段上设置了自动增量。

尝试解决这个问题 2 小时没有成功。

编辑: 数据类:

 public class XYData
 {
   [Column(IsPrimaryKey = true, IsDbGenerated = true)]
   public int Id { get; set; }

   public int BatchId { get; set; }
   public int Channel { get; set; }
   public String Value { get; set; }
   public double Position { get; set; }
   public DateTime Time { get; set; }

   private static Random rand = new Random();

   public XYData(int channel = 0, string val = "")
   {
       Channel = channel;
       Value = val;
       Position = 0;
       Time = DateTime.Now;
   }

   public static List<XYData> genXYData(int howMany, int batchId)
   {
       List<XYData> _allXYData = new List<XYData>();
       for (int i = 0; i < howMany; i++)
       {
           XYData _singleXY = new XYData();
           _singleXY.BatchId = batchId;
           for (int j = 64 * (1 << i); j > 0; j--)
           {
               uint k = (uint)rand.Next(int.MaxValue);
               _singleXY.Value += k.ToString("X8");
           }
           _allXYData.Add(_singleXY); // Add to list
       }
       return _allXYData; // Return list of generated data.
   }
 }

【问题讨论】:

  • 听起来您正在尝试在主键中输入具有相同值的数据,该值必须是唯一的。哪个值是您的主键?如果是 BatchID,BatchID 应该是 Guid,而不是 int,以确保值的唯一性。您可能还想发布 genXYData 的内容,因为您正在编写的示例值可能存在问题。
  • 数据库中的主键是Id,BatchID是其他表的外键。即使我认为它是自动创建的,也没有创建这样的变量还是我错了?
  • 你能说明一下XYData的定义吗?
  • 它是自动创建的,因为它被初始化为默认值 (0)。您将需要使用类似 xy_row.ID = Guid.NewGuid();分配它(或者如果您坚持使用顺序整数,则检查数据库中的最后一个值,但这需要大量额外的数据库调用并创建竞争条件)。您的所有主键都应该是 GUID,除非已经确保它们是唯一的(例如社会保险号),即使这样,我认为将主键与实际数据分开是更好的做法。
  • 那么,在 DB 中,BatchId 是一个 identity 列并由 DB 自动生成吗?我之所以问,是因为在我看来,您的 C# 配置不知道该字段是自动生成的,因此为其分配了默认值“0”。

标签: c# mysql linq devart dotconnect


【解决方案1】:

您的模型定义中可能需要这样的东西 -

[Column(IsPrimaryKey=true, IsDbGenerated=true)]
public int Id { get; set; }

http://www.devart.com/linqconnect/docs/PrimaryKeyMapping.html

【讨论】:

  • 修改为:public class XYData { [Column(IsPrimaryKey = true, IsDbGenerated = true)] public int Id { get; set; } xydata xy_row = new xydata(); **xy_row.id = oneXY.Id;** xy_row.Batchid = (int)oneXY.BatchId; 但还是一样。
  • 如果是新行,则不需要设置 Id 值。如果您选择了身份,数据库应该为您生成它
  • 即使我注释掉xy_row.id = oneXY.Id; 也是一样的。它应该可以工作,但事实并非如此。
  • 发现问题。在由 LinqConnect 生成的 DataModel 中,Id 字段也必须选择为 AutoGenerated。谢谢大家!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-05
  • 1970-01-01
相关资源
最近更新 更多