我现在对这个话题感到困惑,我会很感激如何处理我的问题的提示或解释。
我正在尝试使用ORM将我的对象映射到数据库。我有一个母对象,有几个子元素和子元素。当我将母元素(位置)添加到我的DataContext时,所有子元素也被添加。将新对象插入数据库工作正常。
class Position{
public BE be { get; set; }; // Child element
// and so on...
}
class BE{
[XmlIgnore, Column]
public Nullable<int> Rueckstrom1Id { get; set; }
[XmlElement(typeof(Rueckstrom)), Association(Storage = "rueckstrom1", ThisKey = "Rueckstrom1Id", IsForeignKey = true)]
public Rueckstrom Rueckstrom1 {
get { return this.rueckstrom1.Entity; }
set { this.rueckstrom1.Entity = value; }
}
[XmlIgnore, Column]
public Nullable<int> Rueckstrom2Id { get; set; }
[XmlElement(typeof(Rueckstrom)), Association(Storage = "rueckstrom2", ThisKey = "Rueckstrom2Id", IsForeignKey = true)]
public Rueckstrom Rueckstrom2 {
get { return this.rueckstrom2.Entity; }
set { this.rueckstrom2.Entity = value; }
}
// and so on...
}
class Rueckstrom{
[Column(IsPrimaryKey = true, IsDbGenerated = true, DbType = "Int NOT NULL IDENTITY(1,1)")]
public int Id {
get { return this.id; }
set { this.id = value; }
}
[Column(DbType = "Decimal(8,2)")]
public decimal Sek {
get { return this.sek; }
set { this.sek = value; }
}
// and so on...
}
这是事情: 当我将“Position”元素添加到数据上下文时,如
dataContext.Position.InsertOnSubmit(position);
所有子元素,如“Rueckstrom1”,“Rueckstrom2”,......也被添加到上下文中,最后被插入到数据库中 db.SubmitChanges();
如果我的7个“Rueckstrom”元素之一的“Sek”属性值为0,我想阻止这个插入。
由于数据库尚未生成Id(因此为0),因为它是一个全新的对象,我无法弄清楚如何避免在SubmitChanges上插入某个子元素(类型为“Rueckstrom”) ()。
我知道如果它的“Sek”属性为0,我可以将整个“Rueckstrom”对象设置为NULL,但是由于我在程序中的实现,所有7个“Rueckstrom”子节点总是非NULL。
有什么想法吗?
答案 0 :(得分:1)
我对Linq 2 SQL的一种厌恶是它在以下情况下自动标记要插入的实体:
在DB上设置约束并不能真正解决问题,因为数据上下文仍然会尝试插入实体并像您所经历的那样抛出异常。最好阻止Linq 2 SQL上下文插入这些对象。
Todo我为InsertOnSubmitExplicitly
类创建了一个扩展方法Table
,在您明确设置要插入的实体时,您可能会发现这些方法非常有用。对于那些您不想插入的人(即Sek = 0),您只是不要调用此方法或默认的InsertOnSubmit
方法。
<强>解决方案:强>
public static void InsertOnSubmitExplicitly<TEntity>(this Table<TEntity> table, TEntity obj)
where TEntity : class
{
ChangeSet preSet = table.Context.GetChangeSet();
if (preSet == null)
throw new Exception("Unable to retrieve change set on data context before insert");
table.InsertOnSubmit(obj);
ChangeSet postSet = table.Context.GetChangeSet();
if (postSet == null)
throw new Exception("Unable to retrieve change set on data context after insert");
var markAsDeleted = (from post in postSet.Inserts.Where(n => !ReferenceEquals(n, obj))
join pre in preSet.Inserts on post equals pre into temp1
from t1 in temp1.DefaultIfEmpty()
where t1 == null
select post);
foreach (var entity in markAsDeleted)
table.Context.GetTable(entity.GetType()).DeleteOnSubmit(entity);
}
<强>用法:强>
dataContext.Position.InsertOnSubmitExplicitly(position);
<强>警告:强>
如上面第1点所述,如果您创建一个新实体并从数据上下文为其分配关联实体,它将自动将其标记为插入。但是,就像我在我的解决方案中实现的那样,您可以为数据上下文创建一个显式丢弃所有插入的扩展方法。