C# 多个添加的实体可能具有相同的主键
这是我的3个实体模型:路线、位置和地点路线。C# 多个添加的实体可能具有相同的主键,c#,.net,entity-framework,C#,.net,Entity Framework,这是我的3个实体模型:路线、位置和地点路线。 以下方法失败,并在提交时获取异常: public static Route InsertRouteIfNotExists(Guid companyId, IListLocation> locations) { //Loop on locations and insert it without commit InsertLocations(companyId, routesOrL
以下方法失败,并在提交时获取异常:
public static Route InsertRouteIfNotExists(Guid companyId, IListLocation> locations)
{
//Loop on locations and insert it without commit
InsertLocations(companyId, routesOrLocations);
RouteRepository routeRep = new RouteRepository();
Route route = routeRep.FindRoute(companyId, locations);
if (route == null)
{
route = new Route()
{
CompanyId = companyId,
IsDeleted = false
};
routeRep.Insert(route);
LocationInRouteRepository locInRouteRep = new LocationInRouteRepository();
for (int i = 0; i < locations.Count; i++)
{
locInRouteRep.Insert(new LocationInRoute()
{
//Id = i,
LocationId = locations[i].Id,
Order = i,
RouteId = route.Id
});
}
}
return route;
}
我得到:
无法确定“SimTaskModel.FK_T_STF_SUB_LOCATION_IN_ROUTE_T_STF_LOCATION_id”关系的主端。多个添加的实体可能具有相同的主键
将提交和插入拆分到Methods中时,它会起作用:
public static Route InsertRouteIfNotExists(Guid companyId, IListLocation> locations)
{
//Loop on locations and insert it without commit
InsertLocations(companyId, routesOrLocations);
UnitOfWork.Commit();
RouteRepository routeRep = new RouteRepository();
Route route = routeRep.FindRoute(companyId, locations);
if (route == null)
{
route = new Route()
{
CompanyId = companyId,
IsDeleted = false
};
routeRep.Insert(route);
LocationInRouteRepository locInRouteRep = new LocationInRouteRepository();
for (int i = 0; i < locations.Count; i++)
{
locInRouteRep.Insert(new LocationInRoute()
{
//Id = i,
LocationId = locations[i].Id,
Order = i,
RouteId = route.Id
});
}
UnitOfWork.Commit();
}
return route;
}
公共静态路由InsertRouteIfNotExists(Guid companyId,IListLocation>locations)
{
//在位置上循环并插入它而不提交
插入位置(公司ID、路线或位置);
UnitOfWork.Commit();
RouteRepository routeRep=新的RouteRepository();
Route Route=routeRep.Findulote(公司ID,地点);
如果(路由==null)
{
路由=新路由()
{
CompanyId=CompanyId,
IsDeleted=false
};
路线插入(路线);
LocationInRouteRepository locInRouteRep=新位置InRouteRepository();
对于(int i=0;i
我想在方法之外调用commit一次。在第一个示例中失败的原因以及此异常意味着什么?该错误是由无法解决的外键ID(与引用相反)引起的。在本例中,您有一个LocationInRole,它引用ID为0的位置。有多个位置具有此ID 这些位置尚未分配ID,因为它们尚未保存到生成ID时的数据库中。在第二个示例中,位置在访问其ID之前被保存,这就是为什么这样做的原因 如果只想稍后保存更改,则无法依赖位置ID来定义关系 交换以下行
LocationId = locations[i].Id
…为了这个
Location = locations[i]
然后,这些关系将基于不依赖于LocationID的对象引用。如果这对将来的读者有任何用处,则在我的情况下,此错误是由于数据库中的外键配置不正确(以及从DB生成的模型) 我有桌子:
Parent (1-1) Child (1-many) Grandchild
而且孙子表无意中收到了一个外键,该外键指向它的父(子)和祖父母(父)。从new中保存多个父实体时,我收到此错误。修复方法是更正外键。遇到相同的错误后,我高度怀疑实际问题是位置的定义。简单地说,在EF代码中,首先我打赌它是这样的:
public class Location
{
public int Id { get; set; }
...
public Location ParentLocation { get; set; }
[ForeignKey("ParentLocation")]
public int ParentLocationId { get; set; }
}
换句话说,在问题中,ParentLocation/ParentLocationId是返回到此表的递归引用
ParentLocationId不可为空。这意味着它将被插入一个0,EF将在插入时抱怨,而不是在迁移时抱怨-即使事实是一旦迁移运行,您就有一个表EF将永远不会让您插入
使递归引用返回到同一个表的唯一方法是使递归引用为空:
public class Location
{
public int Id { get; set; }
...
public Location ParentLocation { get; set; }
[ForeignKey("ParentLocation")]
public int? ParentLocationId { get; set; }
}
对于搜索此异常的用户,请注意
int
后面的?
:在我的例子中,它未能设置所需的导航属性
public class Question
{
//...
public int QuestionGridItemID { get; set; }
public virtual QuestionGridItem GridItem { get; set; }
//...
public int? OtherQuestionID { get; set; }
public Question OtherQuestion { get; set; }
}
//...
question.OtherQuestion = otherQuestion;
questionGridItem.Questions.Add(question);
dataContext.SaveChanges(); //fails because otherQuestion wasn't added to
//any grid item's Question collection
我也有同样的问题。下面的情景为我解决了。 我认为您必须更改代码,如下所示:
var insertedRoute =routeRep.Insert(route);
.....
insertedRoute.LocationInRoute = new List<LocationInRoute>();
for(....){
var lInRoute = new LocationInRoute(){
....
Route=insertedRoute;
}
insertedRoute.LocationInRoute.Add(lInRoute );
}
var insertedourite=routeRep.Insert(路由);
.....
InsertedRoote.LocationInRoute=新列表();
对于(……){
var lInRoute=新位置inroute(){
....
路线=插入式;
}
InsertedRoote.LocationInRoute.Add(lInRoute);
}
@Ladislav Mrnka:我没有老板,这是我的项目。我真的不知道你从哪里得到这样的印象,我马上问你。你不是唯一一个整天使用电脑的人。免费咨询?有人给任何人保证他的答案吗?我相信这是一个可以在这里提问的论坛,这就是我正在做的。我有很多问题,我相信多亏了这个论坛和像你这样的人,我才有了一个长距离的学习。参与是一个选择。@Ladislav:我只看到一个问得很好的问题,OP的配置文件也没有显示任何过度。您在整个操作范围内使用相同的ObjectContext,还是每个新存储库都有自己的ObjectContext?@Akash Kava:我使用的是相同的ObjectContext。您可以看看我的帖子并告诉我如何解决它吗?我得到了同样的问题:我很感激!当我部署到test env(测试环境)时,我遇到了这个错误…不在dev Environment中有任何想法吗?@Taran如果代码相同,并且您在两个环境中使用相同的过程进行测试(我会检查这些点),那么这看起来确实很奇怪。也许您只是在dev中添加了一个位置(下面是示例)?尝试添加至少两个。我的问题可能是这一个的变体。我将子对象添加到父对象集合中,而没有显式设置子对象的父属性。我希望EF能够解决这个问题,但在我显式设置子对象的父属性之前,收到了与OP相同的错误。希望这对其他人有所帮助。在我的例子中,我(愚蠢地)将主键基表设置为与外键基表和主键列t相同
var insertedRoute =routeRep.Insert(route);
.....
insertedRoute.LocationInRoute = new List<LocationInRoute>();
for(....){
var lInRoute = new LocationInRoute(){
....
Route=insertedRoute;
}
insertedRoute.LocationInRoute.Add(lInRoute );
}