实体框架 - 将ref属性保存到同一个表

时间:2017-09-05 06:22:45

标签: c# sql-server entity-framework

我有这个课程(简化):

    public class Customer
    {
        public int ID { get; set; }
        public string Name { get; set; }

        [InverseProperty("Customers")]
        public virtual Customer ParentCustomer { get; set; }

        [InverseProperty("ParentCustomer")]
        public virtual ICollection<Customer> Customers { get; set; }
    }

但是当我尝试更新“ParentCustomer”时它无法正常工作,我尝试更新它:

var currCostumer = context.Customers.First(a => a.ID == key);
currCostumer.ParentCustomer = context.Customers.First(a => a.ID == 12);
await context.SaveChangesAsync();

我在交易中尝试了两种情况,但没有。我可以在生成的sql中看到它确实更新了除ParentCustomer(ParentCustomerID)字段之外的所有字段。如果我尝试像下面那样检索我的“currCustomer”,我仍然可以看到它引用了正确的客户。但是,如果我在新的webapi请求中尝试它,那就不行了。

var currCostumer = context.Customers.First(a => a.ID == key);
// currCostumer.ParentCustomer is correct here (if same request)

这是模型构建器:

ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Customer>("Customer"); 

1 个答案:

答案 0 :(得分:0)

这是一个模型构建器配置,应该适用于这种自引用父子关系。我也想在模型中公开外键。

public class Customer {
    public virtual Customer ParentCustomer { get; set; }
    public virtual ICollection<Customer> Customers { get; set; }

    /// <summary>
    /// Exposed foreign key of the <see cref="ParentCustomer "/>.
    /// This is optional (might be null), because not every Customer is grouped into another Customer .
    /// </summary>
    public long? ParentCustomerId { get; set; }
}

ModelBuilder.Entity<Customer>()
   .HasMany(x => x.Customers)
   .WithOptional(x => x.ParentCustomer)    // Not all Customers are contained in a parent Customer, therefore this relationship is optional
   .HasForeignKey(x => x.ParentCustomerId)
   .WillCascadeOnDelete(false);            // ON DELETE NO ACTION constraint is necessary or we would introduce multiple cascade paths

请注意,您必须手动实现正确的删除行为,因为在这种情况下我们不能使用级联删除。