如果您拥有2个实体但没有“关系”实体,您将如何删除关系?
假设以下实体......
模型类:
public class DisplayGroup
{
[Key]
public int GroupId { get; set; }
public string Description { get; set; }
public string Name { get; set; }
public ICollection<LookUpGroupItem> LookUpGroupItems { get; set; }
}
public class DisplayItem
{
[Key]
public int ItemId { get; set; }
public string Description { get; set; }
public string FileType { get; set; }
public string FileName { get; set; }
public ICollection<LookUpGroupItem> LookUpGroupItems { get; set; }
}
public class LookUpGroupItem
{
public int ItemId { get; set; }
public DisplayItem DisplayItem { get; set; }
public int GroupId { get; set; }
public DisplayGroup DisplayGroup { get; set; }
}
以下是删除关系的代码。 注意:我不想删除实体,他们只是不再共享关系。
public void RemoveLink(DisplayGroup g, DisplayItem d)
{
_dataContext.Remove(g.LookUpGroupItems.Single(x => x.ItemId == d.ItemId));
}
上述方法会导致错误:
发生了System.ArgumentNullException 消息=值不能为空。
看起来就是这种情况,因为LookUpGroupItems
为空,但是这些是从数据库中调用的。我同意我不想在从数据库中获取Get时加载所有实体关系对象,但是,最有效的方法是什么?
附加说明:此问题与参数null异常无关。它明确说明了如何删除Entity Framework Core中的关系。
答案 0 :(得分:2)
以下 效率最高,但是可靠方式最多
:public void RemoveLink(DisplayGroup g, DisplayItem d)
{
var link = _dataContext.Find<LookUpGroupItem>(g.GroupId, d.ItemId); // or (d.ItemId, g.GroupId) depending of how the composite PK is defined
if (link != null)
_dataContext.Remove(link);
}
简单明了。 Find
方法用于在本地缓存中定位实体或从数据库加载实体。如果找到,则使用Remove
方法将其标记为删除(将在您调用SaveChanges
时应用)。
当实体未包含在本地缓存中时,由于数据库往返而不是最有效的。
效率最高的是使用&#34; stub&#34;实体(仅填充FK属性):
var link = new LookUpGroupItem { GroupId = g.GroupId, ItemId = d.ItemId };
_dataContext.Remove(link);
这只会在调用DELETE
时发出ApplyChanges
SQL命令。但它有以下缺点:
(1)如果_dataContext
已经包含(正在跟踪)具有相同PK的LookUpGroupItem
实体,则Remove
调用会抛出InvalidOperationException
类似的内容&#34;实体类型的实例&#39; LookUpGroupItem&#39;无法跟踪,因为另一个具有键值&#39; GroupId:1,ItemId:1&#39;已被跟踪。附加现有实体时,请确保仅附加一个具有给定键值的实体实例。&#34;
(2)如果数据库表不包含具有指定复合PK的记录,SaveChanges
将抛出DbUpdateConcurrencyException
说&#34;数据库操作预计会影响1行(s )但实际上影响了0行。自加载实体以来,数据可能已被修改或删除。有关理解和处理乐观并发异常的信息,请参阅http://go.microsoft.com/fwlink/?LinkId=527962。&#34; (这种行为实际上被包括我在内的很多人认为是一个错误,但事实就是如此)。
简而言之,只有在为该操作使用短期新创建DbContext
时才能使用优化方法,并且您绝对确定数据库中存在具有此类PK的记录。在所有其他情况下(通常),您应该使用第一种方法。