Introduction
In Linq2Sql, if you want to delete object, it has to be loaded (or attached) first which results in not very clean syntax. There are some solutions on the net that build "DELETE
... WHERE
..." statement. This approach has one problem: it breaks Linq2Sql object tracking. So I created my own implementation that can be invoked like this:
dbContext.Consumers.DeleteByKey(key, null);
If you want to do some custom processing when object is deleted (for example, delete related objects), you can do it like this:
dbContext.Consumers.DeleteByKey(key,
c =>
{
var related = dbContext.ConsumerRelatedObject.Where(x => x.ConsumerId == key);
dbContext.ConsumerRelatedObject.DeleteAllOnSubmit(related);
});
And the function itself:
public static class TableExtensions
{
public static void DeleteByKey<TEntity, TPK>(this Table<TEntity> table,
TPK key, Action<TEntity> onDelete) where TEntity : class
{
var pkProp = (from p in typeof(TEntity).GetProperties()
from c in p.GetCustomAttributes(typeof(ColumnAttribute),
false).OfType<ColumnAttribute>()
where c.IsPrimaryKey
select p).Single();
var param = Expression.Parameter(typeof(TEntity), "param");
var propExpr = Expression.Property(param, pkProp);
var valExpr = Expression.Constant(key, pkProp.PropertyType);
var l = Expression.Lambda<Func<TEntity, bool>>
(Expression.Equal(propExpr, valExpr), param);
var obj = table.Where(l).SingleOrDefault();
if (obj != null)
{
if (onDelete != null) onDelete(obj);
table.DeleteOnSubmit(obj);
}
}
}