EllanJiang/GameFramework · error · GameFrameworkException

Already exist ' ' in data table ' '.

Error message

Already exist '{0}' in data table '{1}'.

What it means

Thrown by DataTable<T>.InternalAddDataRow (invoked via AddDataRow) when a row with the same Id already exists in the table. Rows are keyed by their Id in m_DataSet, so duplicates would silently overwrite data and are rejected instead.

Solutions

  1. Fix the source data so each row has a unique Id.
  2. Check HasDataRow(id) before adding and skip or update duplicates.
  3. Call Clear() on the table before reloading the same dataset.

Example fix

// before
table.AddDataRow(row1); // Id = 42
table.AddDataRow(row2); // Id = 42 -> throws
// after
if (!table.HasDataRow(42)) table.AddDataRow(row2); else /* update/skip */ ;
Defensive patterns

Strategy: validation

Validate before calling

if (table.HasDataRow(row.Id)) { /* update or skip */ } else { table.AddDataRow(row); }

Try / catch

try { table.AddDataRow(row); } catch (GameFrameworkException ex) when (ex.Message.Contains("Already exist")) { Log.Warn($"Duplicate id {row.Id} in {table.Name}"); }

Prevention

When it happens

Trigger: Calling AddDataRow twice with rows whose DataRow Id is identical; loading two data files that both contain a row with the same primary key.

Common situations: Merging exported files from different sources; idempotent re-load of the same table without clearing it first; copy-pasted row in the spreadsheet with the same key column.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


AI-assisted analysis of EllanJiang/GameFramework@d0c010b051 (2026-09-15). Data as JSON: /api/errors/2eaaa20b13643afb. Report an issue: GitHub.

Appendix: source

Thrown at GameFramework/DataTable/DataTableManager.DataTable.cs:507

            /// <returns>循环访问集合的枚举数。</returns>
            IEnumerator IEnumerable.GetEnumerator()
            {
                return m_DataSet.Values.GetEnumerator();
            }

            /// <summary>
            /// 关闭并清理数据表。
            /// </summary>
            internal override void Shutdown()
            {
                m_DataSet.Clear();
            }

            private void InternalAddDataRow(T dataRow)
            {
                if (m_DataSet.ContainsKey(dataRow.Id))
                {
                    throw new GameFrameworkException(Utility.Text.Format("Already exist '{0}' in data table '{1}'.", dataRow.Id, new TypeNamePair(typeof(T), Name)));
                }

                m_DataSet.Add(dataRow.Id, dataRow);

                if (m_MinIdDataRow == null || m_MinIdDataRow.Id > dataRow.Id)
                {
                    m_MinIdDataRow = dataRow;
                }

                if (m_MaxIdDataRow == null || m_MaxIdDataRow.Id < dataRow.Id)
                {
                    m_MaxIdDataRow = dataRow;
                }
            }
        }
    }
}

View on GitHub (pinned to d0c010b051)