Entity Framework - Добавление родителя также пытается добавить дочерний элемент, когда я этого не хочу - PullRequest
1 голос
/ 15 ноября 2011

У меня есть два объекта (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 (выполнив Ignore(p => p.Product); в моей модели WishListItem) и загружать продукт отдельно каждый раз, когда я загружаю свои объекты WishListItem?

Ответы [ 2 ]

1 голос
/ 15 ноября 2011

Я решил свою проблему. Проблема связана с другим свойством объекта 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, поскольку дочерние объекты не были загружены), а затем true при следующей попытке получить * 1009. *. Это заставляет EF думать, что значение изменилось.

Первый элемент, который мы добавили к WishListItems, работал нормально. Это был второй предмет, который сломался. Мы считаем, что SaveChanges() (или что-то до этого) загрузило Продукт для первого WishListItem. SaveChanges() разбивал Продукт первого WishListItem, когда мы добавляли второй элемент.

Итак, короче, будьте осторожны при вычислении значений в Property.get с использованием дочерних объектов, потому что это может укусить вас в задницу.

0 голосов
/ 15 ноября 2011

Это работает для меня без добавления каких-либо новых записей адресов. В этой модели 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();                             
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...