我有一个Asp.Net MVC 5网站,其中包含EntityFramework Code First。在我的网站中,我有一个Restaurant
模型,其中包含以下代码:
public class Restaurant
{
[Required]
public string Name { get; set; }
//....
public virtual IList<RestaurantType> Types { get; set; }
}
RestaurantType
的代码是:
public class RestaurantType
{
[Key]
public int ID { get; set; }
[Required]
public string Type { get; set; }
public virtual Restaurant Restaurant { get; set; }
}
当我尝试从上下文中删除restaurant
时,出现以下错误:
The DELETE statement conflicted with the REFERENCE constraint "FK_dbo.RestaurantTypes_dbo.Restaurants_Restaurant_ID". The conflict occurred in database "aspnet-Test-20131111052251", table "dbo.RestaurantTypes", column 'Restaurant_ID'.
The statement has been terminated.
我有生产中的数据,我想尽可能安静地处理这个问题。我尝试了以下代码:
for (int i = 0; i < restaurant.Types.Count; i++)
{
var type = restaurant.Types[i];
db.RestaurantTypes.Remove(type);
restaurant.Types.Remove(type);
}
db.Restaurants.Remove(restaurant);
await db.SaveChangesAsync();
但我得到同样的错误。我检查了数据库,没有餐馆ID的行。我甚至试过这个:
var list = db.RestaurantTypes.Where(t => t.Restaurant == null || t.Restaurant.ID == restaurant.ID);
foreach (var ib in list)
{
db.RestaurantTypes.Remove(ib);
}
db.SaveChanges();
它也没用。有没有办法让我用C#代码解决这个问题?
答案 0 :(得分:6)
根据您的型号,删除可能实际上并未删除RestaurantTypes中的行。请尝试使用 DeleteObject (请参阅Entity Framework .Remove() vs. .DeleteObject())。另外为了确保在删除所有RestaurantTypes之前没有删除Restaurant,请尝试在删除所有RestaurantTypes后提交更改:
for (int i = 0; i < restaurant.Types.Count; i++)
{
var type = restaurant.Types[i];
db.DeleteObject(type);
restaurant.Types.Remove(type);
}
db.SaveChanges();
db.DeleteObject(restaurant);
db.SaveChanges();
另外,在旁注(这与您的错误消息无关):数据库模型中的关系不是向后的。如果餐厅可以有一个或多个餐厅类型,您应该有从餐厅到餐厅类型的参考。这意味着您需要一个包含关系的附加表(例如RelRestaurantRestaurantType):
--------------- ------------------ ------------------
| | | Rel | | |
| Restaurant | <-- Restaurant_ID -- | Restaurant | -- RestaurantType_ID --> | RestaurantType |
| | | RestaurantType | | |
--------------- ------------------ ------------------
你这样做的方式,每家餐厅都有自己的类型副本。例如。假设你有一个“中国人”类型,你有100家中国餐馆。然后,您最终会在餐厅餐厅中输入100个“中文”条目。
答案 1 :(得分:0)
对您的逻辑(餐厅和餐厅类型)提出异议,餐厅应该是餐厅类型的孩子。
您要做的是级联删除 为了得到这个,你应该在两个表中都有键
public class Restaurant{
public Restaurant()
{
Types=new List<RestaurantType>();
}
[Key]
public int Id{get; set;}
[Required]
public string Name{get; set;}
public virtual ICollection<RestaurantType> Types{get;set;}
}
public class RestaurantType{
[Key]
public int Id{get;set;}
[Required]
public string Type{get; set;}
public int RestaurantId{get; set;}
[ForeignKey("RestaurantId")]
public Restaurant Restaurant{get;set;}
}
并且您的代码将正确执行 但请确保您的逻辑是正确的,实际上我知道餐厅只有一种类型,而不是很多
问候