我首先使用EF5代码。
我们有一种方法
LogHistoryTracking(DbEntityEntry entity)
在调用SaveChanges
时进行日志更改。
在SaveChanges
上,我们获得了更改的实体并传递到logHistoryTracking
var changedEntities = ChangeTracker.Entries().ToList();
但是当我访问
changedEntity.OriginalValues.PropertyNames
外国键对象没有属性(仅外国密钥ID-但是当这里只有ID时,我们如何获取数据?)。
我也尝试使用Google寻求解决方案,但是这个问题可能并不那么受欢迎。
有这篇文章,但不起作用。
感谢任何帮助。谢谢。
如果要使您的实体属性可访问,则必须在访问它们之前将它们包含在'之前。就像以下示例中获得第一个cutomer的订单:
var orders = context.Customers
.Include("Orders")
.First().Orders;
在此示例中,如果您不致电.Include("Orders")
,您将没有客户。如果您有外键并且忘记包括外键的导航属性,也是如此。这是因为密钥(ID)是对象的一部分,而导航属性不是。
让我们看看一个现实世界的例子:
public class Employee : Entity
{
public virtual int CompanyUserId { get; set; }
public virtual CompanyUser CompanyUser { get; set; }
//... cut out for brevity
}
如果您得到这样的员工:
var employees = context.Employees;
您将无法访问员工[0] .companyuser之后context.savechanges()由于懒惰加载。连接是在上下文后处理的。
,如果您致电:
var employees = context.Employees
.Include("CompanyUser")
.ToArray();
您将能够立即访问员工[0] .companyuser.someproperty。
如果您致电:
var employees = context.Employees
.Include("CompanyUser");
然后,即使在context.savechanges()带有懒惰加载的情况下,您也将拥有员工[0] .companyuser.someproperty,因为您已告诉EF在执行查询之前将" Companyuser"属性包括在内。执行EF将包括命名属性。
更新拦截DBContext至少可以通过两种不同的方式完成。 first - 覆盖savechanges()或savechangesasync,因为它是虚拟的:
public class MyDbContext : DbContext
{
public event Action<MyDbContext> SavingChanges = _ => { };
public override int SaveChanges()
{
this.SavingChanges(this);
return base.SaveChanges();
}
}
第二没有直接覆盖的方式是隐藏这样的界面内部的dbcontext(这是来自Real Project):
public interface IUnitOfWork : IDisposable
{
void Commit();
}
第三方法(有些不同)是拦截DB调用。第四存在存在,但这取决于您使用的IOC。如果您使用温莎城堡,则可以使用拦截器。我想每个IOC都有其自己的拦截方式。