Closed Nc32 closed 6 years ago
Could you post the rest of the relevant code? I can't tell for sure what's happening here without seeing your DbContext
class.
One thing that stands out to me is that you're making another instance of ApplicationDbContext
. This library is designed to work well in most scenarios by using the context instance which has triggered the event. You can access the context instance at entry.Context
.
I change my code to
Triggers<Product>.Inserted += entry =>
{
var db = entry.Context;
var recd = new ProductRecord();
recd.Id = Guid.NewGuid().ToString();
recd.Date = DateTime.Now;
recd.Operation = ProductRecordOperationType.Insert;
db.Entry(recd).State = System.Data.Entity.EntityState.Added;
db.SaveChanges();
};
But the problem is the same.
Here is my DbContext, which is also an IdentityDbContext from WebAPI template. It works fine until add Triggers.
Now there are two things changed. One is this issue,the other is EF can't generate Id(I have to manually generate Product.Id and PushProductRecord.Id, Product can be saved to Database) Are they relate to a same problem?
public class ApplicationDbContext : IdentityDbContext<ApplicationUser, IdentityRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>
{
public ApplicationDbContext()
: base("name=ApplicationContext")
{
this.Configuration.AutoDetectChangesEnabled = false;
}
public virtual DbSet<Product> Product { get; set; }
public virtual DbSet<ProductRecord> PushProductRecord { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Product>().Map(m =>
{
m.MapInheritedProperties();
m.ToTable("Product");
});
base.OnModelCreating(modelBuilder);
}
#region Override EF 6 SaveChange to enable triggers
public override Int32 SaveChanges()
{
return this.SaveChangesWithTriggers(base.SaveChanges);
}
public override Task<Int32> SaveChangesAsync(CancellationToken cancellationToken)
{
return this.SaveChangesWithTriggersAsync(base.SaveChangesAsync, cancellationToken);
}
#endregion
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
Finally figure out the problem is using MapInheritedProperties. The problem is "After install EntityFramework.Triggers or one of its dependencies, use MapInheritedProperties will cause error"
you can try this
public class test
{
public int id { get; set; }
}
public class context : DbContext
{
public context() : base("DefaultConnection")
{ }
public virtual DbSet<test> tests { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<test>().Map(m =>
{
m.MapInheritedProperties();
});
base.OnModelCreating(modelBuilder);
}
}
It works fine with only EntityFramework. But after install EntityTriggers(or one of its dependencies, i didnt test), errors happen. Since all these dependencies are maintance by you,should I leave this issue as a bug report or open a new one in somewhere else?
Let's keep the discussion in this issue until we reproduce the bug. Thank you for your effort. Could you post your whole test program? The one which reproduces the error?
public class test
{
[Key]
// [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int id { get; set; }
public string name { get; set; }
static test()
{
Triggers<test>.Inserted += entry =>
{
var db = entry.Context;
var entity = entry.Entity;
var rec = new testRecord()
{
id = 1,
name = entity.name,
opt = 1
};
db.Entry(rec).State = EntityState.Added;
db.SaveChanges();
};
}
}
public class testRecord : test
{
public int opt { get; set; }
}
public class context : DbContext
{
public virtual DbSet<test> tests { get; set; }
public virtual DbSet<testRecord> testRecords { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<testRecord>().Map(m =>
{
m.MapInheritedProperties()
.ToTable("testRecord");
});
base.OnModelCreating(modelBuilder);
}
#region Override EF 6 SaveChange to enable triggers
public override Int32 SaveChanges()
{
return this.SaveChangesWithTriggers(base.SaveChanges);
}
public override Task<Int32> SaveChangesAsync(CancellationToken cancellationToken)
{
return this.SaveChangesWithTriggersAsync(base.SaveChangesAsync, cancellationToken);
}
#endregion
}
class Program
{
static void Main(string[] args)
{
using (var db = new context())
{
var t = new test()
{
// id = 0,
name = "test Entity"
};
db.tests.Add(t);
db.SaveChanges();
}
Console.WriteLine("done");
}
}
To reproduce the same bug,follow these steps 1.create a new console application, paste the codes above. 2.nuget install entity.triggers 3.Enable-Migrations, Update-database, create a table without DatabaseGeneratedAttribute. 4.uncomment DatabaseGeneratedAttribute, Update-databse. 5.Run console.
I did'n try to do this with only EF, I think CodeFirst is able to update-database correctly.
So i get the error, but if i comment-out the trigger code, i still get the error. Are you sure the error is caused by this library?
Maby this helps: With post triggers I use next constraction without execute SaveChange in triggers
while (dbContext.ChangeTracker.HasChanges())
{
dbContext.SaveChanges();
}
I have 2 DbSet, one is Product another is ProductRecord. And I want to record every changes of Product into ProductRecord. here is my code.
Error Message says that I'm tring to add an entity with Id=null
And I also tried add an Inserting Trigger to ProductRecord to ensure every record has ID, still dosent work.