我想知道如果表中没有记录,是否有更简单的方法来插入记录。我还在尝试构建我的LINQ to SQL技能。
这就是我所拥有的,但似乎应该有一种更简单的方法。
public static TEntity InsertIfNotExists<TEntity>
(
DataContext db,
Table<TEntity> table,
Func<TEntity,bool> where,
TEntity record
)
where TEntity : class
{
TEntity existing = table.SingleOrDefault<TEntity>(where);
if (existing != null)
{
return existing;
}
else
{
table.InsertOnSubmit(record);
// Can't use table.Context.SubmitChanges()
// 'cause it's read-only
db.SubmitChanges();
}
return record;
}
答案 0 :(得分:14)
public static void InsertIfNotExists<TEntity>
(this Table<TEntity> table,
TEntity entity,
Expression<Func<TEntity,bool>> predicate)
where TEntity : class
{
if (!table.Any(predicate))
{
table.InsertOnSubmit(record);
table.Context.SubmitChanges();
}
}
table.InsertIfNotExists(entity, e=>e.BooleanProperty);
答案 1 :(得分:12)
正如其他人所指出的,if (!Any()) { InsertOnSubmit(); }
解决方案都有竞争条件。如果你走这条路线,当你拨打SubmitChanges
时,你必须考虑a)a SqlException
可以为重复插入引发,或者b)你可能在表中有重复的记录
幸运的是,我们可以通过强制执行唯一性来使用数据库来避免竞争条件。以下代码假定表上存在主键或唯一约束,以防止插入重复记录。
using (var db = new DataContext()) {
// Add the new (possibly duplicate) record to the data context here.
try {
db.SubmitChanges();
} catch (SqlException ex) {
const int violationOfPrimaryKeyContraint = 2627;
const int violationOfUniqueConstraint = 2601;
var duplicateRecordExceptionNumbers = new [] {
violationOfPrimaryKeyContraint, violationOfUniqueConstraint
};
if (!duplicateRecordExceptionNumbers.Contains(ex.Number)) {
throw;
}
}
}
现在......如果你必须在与其他数据库更新的批处理事务中执行插入,事情会变得更加复杂。
答案 2 :(得分:5)
同意marxidad's answer,但请参阅备注1.
注1:恕我直言,在帮助方法中调用db.SubmitChanges()
是不明智的,因为你可能会破坏上下文事务。这意味着如果您在多个实体的复杂更新过程中调用InsertIfNotExists<TEntity>
,则不会立即保存更改,而是逐步保存更改。
注2:InsertIfNotExists<TEntity>
方法是一种非常通用的方法,适用于任何场景。如果您只想区分从数据库加载的实体与从代码中创建的实体,您可以使用Entity类的部分方法OnLoaded
,如下所示:
public partial class MyEntity
{
public bool IsLoaded { get; private set; }
partial void OnLoaded()
{
IsLoaded = true;
}
}
鉴于(和注释1),然后将InsertIfNotExists功能简化为以下内容:
if (!record.IsLoaded)
db.InsertOnSubmit(record);
答案 3 :(得分:4)
马克答案的小修改:
如果您只关心通过主键检查实体是否存在,可以像这样使用Marke的答案:
public static void InsertIfNotExists<TEntity>
(this Table<TEntity> table
, TEntity entity
) where TEntity : class
{
if (!table.Contains(entity))
{
table.InsertOnSubmit(entity);
}
}