实体框架 - 添加父级也试图在我不希望的时候添加子级

时间:2011-11-14 21:14:27

标签: entity-framework

我有两个对象(WishListItem和Product)的一对多关系。 WishListItem必须有一个产品。每个产品都可以在0-n WishListItems。

public class WishListItem
{
    public int Id { get; set; }
    public int ProductId { get; set; }
    public Product Product { get; set; }
}

public class Product
{
    public int Id { get; set; }
    // ... other properties
}

产品不了解WishListItems。所有产品都存在。我只想添加一个新的WishListItem。关系的我的WishListItem模型是这样的:

HasRequired(p => p.Product).WithMany().HasForeignKey(p => p.ProductId);

当我尝试添加这样的新项目时:

WishListItem item = new WishListItem();

// ... sets properties

WishListItems.Add(item);  // WishListItems is of type DbSet<WishListItem>

SaveChanges();

此代码似乎也尝试添加产品。我不想添加新产品(甚至更新它)。 Product属性设置为null。如何告诉Entity Framework我只想添加WishListItem?我是否需要忽略Product属性(通过在WishListItem模型中执行Ignore(p => p.Product);)并在每次加载WishListItem对象时单独加载Product?

2 个答案:

答案 0 :(得分:1)

我已经解决了我的问题。问题来自Product对象上的另一个属性。

private bool _isFreeShippingInitialValue;

public bool IsFreeShipping
{
    get
    {
        return _isFreeShippingInitialValue ||
            computedValueFromAnotherChildObject;
    }
    set
    {
        _isFreeShippingInitialValue = value;
    }
}

我们注意到,当您第一次获取Product对象时,在加载任何子对象之前调用IsFreeShipping.get(不确定原因)。例如,如果_isFreeShippingInitialValue为false且computedValueFromAnotherChildObject为true,则IsFreeShipping首先返回false(因为computedValueFromAnotherChildObject首先为false,因为没有加载子对象),然后为真下次你试图获得IsFreeShipping。这使得EF认为价值已发生变化。

我们添加到WishListItems的第一项工作正常。这是破产的第二个项目。我们认为SaveChanges()(或之前的某些内容)为第一个WishListItem加载了产品。当我们添加第二个项目时,SaveChanges()打破了第一个WishListItem的产品。

因此,简而言之,在使用子对象计算Property.get中的值时要小心,因为它可能会咬你的屁股。

答案 1 :(得分:0)

这适用于我而不添加任何新的地址记录。在这个模型中,Person有一个可选的家庭住址,但是地址对这个人没有任何了解。

public class Person 
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public virtual Address HomeAddress { get; set; }
    public int HomeAddress_id { get; set; }
}

public class Address 
{
    public int Id { get; set; }
    public string PhoneNumber { get; set; }
    public string Street { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Country { get; set; }
}

DbContext覆盖中,我有以下代码

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Person>()
        .HasRequired(t => t.HomeAddress).WithMany()
        .HasForeignKey(t => t.HomeAddress_id);
}

我可以写这样的单元测试。

var addressId = 0;
using (var db = new DataContext())
{
    var address = new Address { City = "test", Country = "test", PhoneNumber = "test", State = "test", Street = "test" };
    db.Addresses.Add(address);
    db.SaveChanges();
    addressId = address.Id;
}

using (var db = new DataContext())
{
    var person = new Person { Email = "test@test.com", FirstName = "Testy", LastName = "Tester", HomeAddress_id = addressId };
    db.Persons.Add(person);
    db.SaveChanges();                             
}