Сохранение сущности вызывает двойную вставку в данные поиска - PullRequest
2 голосов
/ 15 апреля 2011

Я использую EF 4.1 «сначала код» для создания моих БД и объектов.

Дано:

public class Order 
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual OrderType OrderType { get; set; }
}

public class OrderType 
{
    public int Id { get; set; }
    public string Name { get; set; }
}

Заказ имеет один тип заказа.Тип заказа - это просто справочная таблица.Значения не меняются.Используя Fluent API:

//Order
ToTable("order");
HasKey(key => key.Id);
Property(item => item.Id).HasColumnName("order_id").HasColumnType("int");
Property(item => item.Name).HasColumnName("name").HasColumnType("string").HasMaxLength(10).IsRequired();

HasRequired(item => item.OrderType).WithMany().Map(x => x.MapKey("order_type_id")).WillCascadeOnDelete(false);

//OrderType
ToTable("order_type");
HasKey(key => key.Id);

Property(item => item.Id).HasColumnName("order_type_id").HasColumnType("int");
Property(item => item.Name).HasColumnName("name").HasColumnType("nvarchar").HasMaxLength(100).IsRequired(); 

Теперь в нашем приложении мы загружаем все наши данные поиска и кешируем их.

var order = new Order
{
   Name = "Bob"
   OrderType = GetFromOurCache(5) //Get order type for id 5
};

var db = _db.GetContext();
db.Order.Add(order);
db.SaveChanges();

Наш заказ «Вы - beaut» сохранен, но с новым типом заказа,любезно предоставлено EF.Так что теперь у нас есть два одинаковых типа заказа в нашей базе данных.Что я могу сделать, чтобы изменить это поведение?

TIA

Ответы [ 3 ]

6 голосов
/ 15 апреля 2011

С EF 4.1 вы можете сделать это перед вызовом SaveChanges:

db.Entry(order.OrderType).State = EntityState.Unchanged;
2 голосов
/ 15 апреля 2011

В качестве альтернативы решению Якимича вы можете прикрепить OrderType к контексту, прежде чем добавить ордер, чтобы EF знал, что OrderType уже существует в базе данных:

var order = new Order
{
    Name = "Bob"
    OrderType = GetFromOurCache(5) //Get order type for id 5
};

var db = _db.GetContext();
db.OrderTypes.Attach(order.OrderType);
db.Order.Add(order);
db.SaveChanges();
0 голосов
/ 18 апреля 2011

Якимыч / Слаума - спасибо за ответы. Интересно, что я пробовал оба пути и ни один не работал. Отсюда и я задал вопрос. Ваши ответы подтвердили, что я, должно быть, что-то делаю не так, и, конечно же, я не управлял своим dbContext должным образом.

Тем не менее, EF автоматически хочет вставить справочные / статические данные, даже когда вы предоставляете полный объект (включая уникальный идентификатор поискового запроса). Это заставляет разработчика не забывать устанавливать состояние. Чтобы сделать вещи немного проще, я делаю:

var properties = entry.GetType().GetProperties().Where(x => x.PropertyType.GetInterface(typeof(ISeedData).Name) != null);
foreach (var staticProperty in properties)
{
    var n = staticProperty.GetValue(entry, null);
    Entry(n).State = EntityState.Unchanged;
}  

в переопределении SaveChanges.

Еще раз спасибо за помощь.

...