【问题标题】:Changing the order of LINQ to SQL Inserts更改 LINQ to SQL 插入的顺序
【发布时间】:2026-01-24 11:55:01
【问题描述】:

我有两个 LINQ to SQL 类,CandyBar 和 DeliciousCandyBar,它们映射到 SQL Server 中的同名表。

CandyBar 和 DeliciousCandyBar 之间存在 0..1 的关系。即,一个 CandyBar 可以有 0 或 1 个 DeliciousCandyBar。相反,一个 DeliciousCandyBar 正好有一个 CandyBar。

在 LINQ to SQL 类中,它们看起来(基本上)像

class CandyBar {
  public int Id { get;set;} // this is primary key w/ autoincrement identity
  public string Name {get;set;}
  public EntityRef<DeliciousCandyBar> DeliciousCandyBar {get;set;}
}

class DeliciousCandyBar {
  public int DeliciousnessFactor {get;set;}
  public int CandyBarId {get;set;} // FK to candyBar Id
  public EntityRef<CandyBar> CandyBar {get;set;} // the association property of the FK
}

为了向数据库提供数据(通过 l2sql),我的爬虫出去寻找糖果棒和美味的糖果棒。

但是,当我的爬虫插入 CandyStoreDataContext 中的第一个美味糖果棒时,调用 SubmitChanges 时 DataContext 会引发异常。

爬虫为一个美味的糖果条运行以下代码。请注意,这是一个示例。确切的过程更复杂,我使用了一个自定义的 DSL 爬虫来吐出这个对象结构。本质上,执行以下操作。

var dc = CandyStoreDataContext();
var bar = new CandyBar() {
    Name = "Flake",
    DeliciousCandyBar = new DeliciousCandyBar() {
      DeliciousnessFactory = 12
    }
};

dc.CandyBars.InsertOnSubmit(bar);

dc.SubmitChanges();

在 SubmitChanges() 上,抛出 SqlException 并显示消息“INSERT 语句与 FOREIGN KEY 约束 FK_CandyBar_DeliciousCandyBar 冲突。冲突发生在数据库 CandyStoreData、表 'dbo.DeliciousCandyBar'、列 'CandyBarId'”中。

当我将 CandyStoreDataContext.Log 转储到 Console.Out 时,问题变得清晰,生成的插入语句以错误的方式进行。 LINQ to SQL 试图先插入 DeliciousCandyBar(它试图在 CandyBarId 列中设置无效值),而不是先插入 CandyBar。

我的问题是,如何让 Linq to SQL 与插入语句的顺序交换?

我曾(错误地)假设 LINQ to SQL 会知道关系依赖的方向并反过来做。

更新:

This post 表明我的协会是错误的。但这对我来说没有意义。在数据库中建模时是有意义的。怎么可能反过来呢。

在 CandyBar 上,DelciousCandyBar 属性的关联属性是 [Association(Name="DeliciousCandyBar_CandyBar", Storage="_DeliciousCandyBar", ThisKey="Id", OtherKey="CandyBarId", IsForeignKey=true)]

在 DeliciousCandyBar 上,CandyBar 属性的关联属性是 [Association(Name="DeliciousCandyBar_CandyBar", Storage="_CandyBar", ThisKey="CandyBarId", OtherKey="Id", IsUnique=true, IsForeignKey=false)]

好吧,现在我很困惑,为什么第二个属性被标记为外键。

我将尝试在 SQL Management Studio 中重新创建 CandyBar 和 DeliciousCandyBar 之间的关系

更新 2

好的,我尝试以两种方式创建关系。并且 SSMS 非常清楚主键的位置(CandyBar.Id)。我第一次做对了。否则,级联会倒退。

【问题讨论】:

    标签: c# .net sql linq-to-sql


    【解决方案1】:

    我会考虑它是一个带有自引用表的 linq2sql 错误的可能性。这是一个疯狂的猜测,但我记得 linq2sql 文档在某处说它不支持它。也许是它的 linq2sql 设计器感到困惑。

    从您发布的生成属性中,您可以看出它是向后的,即 CandyBar 指向的是美味,而不是相反。查看生成的代码以了解其他正常工作的关系。

    一旦您确认它不起作用,并且通过在设计器中重新添加它们并没有正确设置它们,请在设计器中打开工作关联的属性并确保具有 candybar 和deliciouscandy 之间的关联以同样的方式配置。

    【讨论】:

      【解决方案2】:

      请尝试这个替代方案:

      1. 插入不带任何子DeliciousCandyBar 对象的CandyBar 实例,然后调用SubmitChanges() 方法。

      2. 假设您有一个 ID 或 GUID 链接这两个对象 - 比如说,CandyBarID。然后将DeliciousCandyBar实例上CandyBarID的值设置为CandyBar实例的值。

      3. 然后您可以插入DeliciousCandyBar 对象,并且由于已设置CandyBarID,因此在选择CandyBar 对象时关系应该是正确的。

      【讨论】: