调用SaveChanges()时如何获取外键的导航属性



我首先使用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都有其自己的拦截方式。

相关内容

  • 没有找到相关文章

最新更新