ich eine Datenbank implementiert haben soft löschen (ein boolesches Flag, die Einträge als gelöscht markiert) mit dem folgenden Tutorial: http://www.codeguru.com/csharp/csharp/soft-deleting-entities-cleanly-using-entity-framework-6-interceptors.htmlEntity Framework soft löschen Implementierung mit Datenbank-Abfangjäger nicht funktioniert
Es mir da einmal eine sehr gute Umsetzung scheint eingerichtetes Löschen wird auf ein Modell angewendet, indem einfach eine [SoftDelete("IsDeleted")]
Annotation hinzugefügt wird. Das Problem ist so weit, dass es nicht funktioniert.
Die Quelle scheint zuverlässig zu sein, und sie veröffentlichte auch ein Beispiel für ihre Lösung: https://github.com/rakeshbabuparuchuri/EFExpensionPoints
Können Sie einen Blick auf meinem Code in Fall haben ich falsch gemacht hätte etwas bei der Anwendung des weichen mein Projekt löschen?
Dies ist das Modell:
[SoftDelete("IsDeleted")]
public class BC_Instance
{
public int ID { get; set; }
public bool IsDeleted { get; set; }
}
ApplicationDbContext.cs:
namespace bcplatform2.Models
{
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
// Add a DbSet for each one of your Entities
//public DbSet<VirtualGuest> VirtualGuests { get; set; }
public DbSet<BC_Instance> BiocloudInstances { get; set; }
static ApplicationDbContext()
{
Database.SetInitializer<ApplicationDbContext>(new ApplicationDbInitializer());
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
protected new void OnModelCreating(DbModelBuilder modelBuilder)
{
var conv = new AttributeToTableAnnotationConvention<SoftDeleteAttribute, string>(
"SoftDeleteColumnName",
(type, attributes) => attributes.Single().ColumnName);
modelBuilder.Conventions.Add(conv);
}
}
}
ApplicationDbConfiguration.cs
SoftDeleteAttribute.cs:
namespace bcplatform2.Helpers
{
public class SoftDeleteAttribute : Attribute
{
public SoftDeleteAttribute(string column)
{
ColumnName = column;
}
public string ColumnName { get; set; }
public static string GetSoftDeleteColumnName(EdmType type)
{
MetadataProperty annotation = type.MetadataProperties
.Where(p => p.Name.EndsWith("customannotation:SoftDeleteColumnName"))
.SingleOrDefault();
return annotation == null ? null : (string)annotation.Value;
}
}
}
SoftDeleteInterceptor.cs
Ich bemerkte, dass SoftDeleteAttribute.GetSoftDeleteColumnName(deleteCommand.Target.VariableType.EdmType)
nicht das weiche Lösch Attribut nicht finden und gibt null zurück. Aber ich weiß nicht warum.
namespace bcplatform2.Helpers
{
public class SoftDeleteInterceptor : IDbCommandTreeInterceptor
{
public void TreeCreated(DbCommandTreeInterceptionContext interceptionContext)
{
if (interceptionContext.OriginalResult.DataSpace == DataSpace.SSpace)
{
var queryCommand = interceptionContext.Result as DbQueryCommandTree;
if (queryCommand != null)
{
var newQuery = queryCommand.Query.Accept(new SoftDeleteQueryVisitor());
interceptionContext.Result = new DbQueryCommandTree(
queryCommand.MetadataWorkspace,
queryCommand.DataSpace,
newQuery);
}
var deleteCommand = interceptionContext.OriginalResult as DbDeleteCommandTree;
if (deleteCommand != null)
{
var column = SoftDeleteAttribute.GetSoftDeleteColumnName(deleteCommand.Target.VariableType.EdmType);
if (column != null)
{
var setClauses = new List<DbModificationClause>();
var table = (EntityType)deleteCommand.Target.VariableType.EdmType;
if (table.Properties.Any(p => p.Name == column))
{
setClauses.Add(DbExpressionBuilder.SetClause(
DbExpressionBuilder.Property(
DbExpressionBuilder.Variable(deleteCommand.Target.VariableType, deleteCommand.Target.VariableName),
column),
DbExpression.FromBoolean(true)));
}
var update = new DbUpdateCommandTree(
deleteCommand.MetadataWorkspace,
deleteCommand.DataSpace,
deleteCommand.Target,
deleteCommand.Predicate,
setClauses.AsReadOnly(),
null);
interceptionContext.Result = update;
}
}
}
}
}
}
IdentityConfig.cs
public class ApplicationDbInitializer : DropCreateDatabaseIfModelChanges<ApplicationDbContext>
{
protected override void Seed(ApplicationDbContext context)
{
InitializeIdentityForEF(context);
base.Seed(context);
}
//Create [email protected] with [email protected] in the Admin role
public static void InitializeIdentityForEF(ApplicationDbContext db)
{
//Initialize users and roles...
}
}
Wenn ich überschreibe, wird das ursprüngliche OnModelCreating nicht aufgerufen und das sollte nicht der Fall sein. 'new' andererseits lässt beide Methoden aufrufen. – nest
Das ist nicht korrekt. Sie sollten überschreiben und dann base.OnModelCreating aufrufen, um an die Standardmethode zu delegieren (falls Sie dies wünschen). Setzen Sie einfach einen Haltepunkt in der aktuellen Methode und testen Sie, ob es stoppt, Sie werden sehen, dass es nicht funktioniert. – tede24
@ tede24 ist richtig! –