我首先使用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; }
}
订单有一个ordertype。订单类型只是一个查找表。价值观不会改变。使用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();
我们的优惠订单已保存,但新订单类型,由EF提供。所以现在我们的数据库中有两个相同的订单类型。我该怎么做才能改变这种行为?
TIA
答案 0 :(得分:6)
使用EF 4.1,您可以在致电SaveChanges
之前执行此操作:
db.Entry(order.OrderType).State = EntityState.Unchanged;
答案 1 :(得分:2)
除了Yakimych的解决方案之外,您还可以在添加订单之前将附加上下文,以让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();
答案 2 :(得分:0)
Yakimych / Slauma - 感谢答案。有趣的是我尝试了两种方式,但都没有奏效。因此我问了这个问题。你的回答证实我一定做错了,果然我没有正确管理我的dbContext。
即使您提供完整对象(包括查找唯一ID),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覆盖。
再次感谢您的帮助。