更改LINQ到SQL插入的顺序

时间:2009-04-01 14:14:25

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

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

CandyBar和DeliciousCandyBar之间存在0..1关系。即,CandyBar可以有0或1个DeliciousCandyBars。相反,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的第一个美味糖果条时,DataContext会在调用SubmitChanges时抛出异常。

抓取工具为一个美味的直板运行以下代码。请注意这是一个例子。确切的过程更复杂,我使用自定义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与insert语句的顺序交换?

我曾(假设)错误地认为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)。我第一次就做对了。否则,级联会倒退。

2 个答案:

答案 0 :(得分:0)

请尝试这个替代方案:

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

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

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

答案 1 :(得分:0)

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

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

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