2011-05-18 61 views
60

这是我的3个实体模型:Route,Location和LocationInRoute。
model多个添加的实体可能具有相同的主键

以下方法失败,当提交它得到的异常:

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; 
     } 

在做:

InsertRouteIfNotExists(companyId, locations); 
UnitOfWork.Commit(); 

我:

无法确定的主要终点'SimTaskModel.FK_T_STF_SUB_LOCATION_IN_ROUTE_T_STF_LOCATI'的ON_location_id'关系。多个添加的实体可能具有相同的主键。

在分割提交并插入到methos - 它的工作原理:

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; 
      } 

我想调用commit一次和方法之外。为什么它在第一个例子中失败了,这个例外意味着什么?

+4

@Ladislav Mrnka:我没有老板,这是我的项目。我真的不知道你的印象是我立即问到的。你不是唯一一个整天使用电脑的人。免费咨询?有人为他的答案提供任何保证吗?我相信这是一个论坛,可以在这里问问题,这就是我正在做的事情。我有很多问题,我相信我会通过这个论坛和像你这样的人来进行长期的学习。参与是一个选择。 – Naor 2011-05-18 07:35:33

+0

@拉迪斯拉夫:我只看到一个相当好的问题,而且OP的个人资料也没有显示任何事情。 – 2011-05-18 09:22:24

+0

您是否在整个操作范围内使用相同的ObjectContext,或者每个新的Repository都有自己的ObjectContext? – 2011-05-19 15:51:59

回答

123

该错误是由无法解析的外键ID(而不是参考)引起的。在你的情况下,你有一个LocationInRole引用一个ID为0的位置。有多个位置使用这个ID。

位置还没有被分配一个ID,因为他们还没有被保存到生成ID时的数据库。在你的第二个例子中,位置在它们的ID被访问之前被保存,这就是为什么这是有效的。

如果您稍后想要SaveChanges,您将无法依靠位置ID来定义关系。

交换下面的行...

LocationId = locations[i].Id 

...这个...

Location = locations[i] 

的关系将被基于对象的引用这是不依赖于LocationIDs。

+0

你也节省了我的一天:) – senzacionale 2014-10-10 15:10:42

+0

你们两个都可以看看我的文章,并告诉我如何解决它,我得到同样的问题:http://stackoverflow.com/questions/26783934/foreign-密钥循环或级联路径我很感激它! – 2014-11-06 23:44:10

+0

谢谢,它真的有帮助:-) – user261002 2014-12-04 13:44:06

4

如果这对未来的读者有任何用处,在我的情况下,这个错误是由于在我的数据库(和从DB生成的模型)中配置不正确的外键。

我有表:

Parent (1-1) Child (1-many) Grandchild 

和孙表无意中收到一个外键到它的父(儿童)和它的祖父(母)。在保存新的多个Parent实体时,我收到了这个错误。修复一直在纠正外键。

+0

在我的情况下,我(愚蠢)将我的主键基表设置为与我的外键基表和我的主键列相同我的外键列*弓头羞辱* 希望这可以帮助别人.. – Dave 2016-08-16 13:21:26

0

遇到同样的错误我高度怀疑实际问题是定位的位置。简单地说,在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会在Insert上投诉,而不是在你迁移时 - 即使事实是迁移运行一次,你有一张表EF永远不会让你插入。

做一个递归引用回到同一表工作的唯一方法是使递归引用可为空:

public class Location 
{ 
    public int Id { get; set; } 
    ... 
    public Location ParentLocation { get; set; } 
    [ForeignKey("ParentLocation")] 
    public int? ParentLocationId { get; set; } 
} 

注意?int后。

+0

Wouldn如果在创建子位置之前在父位置上执行SaveChanges,那么旧的(不可为空)版本工作? – 2017-06-22 14:56:58

+1

忽略以上,我是个白痴。您将无法创建第一个位置。 – 2017-06-22 14:58:48

0

对于那些寻找这个例外:
在我的情况下,它没有设置所需的导航属性。

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 
0

我有同样的问题。以下情景为我解决。 我想你必须改变你的代码如下:

var insertedRoute =routeRep.Insert(route); 
..... 
insertedRoute.LocationInRoute = new List<LocationInRoute>(); 
for(....){ 
    var lInRoute = new LocationInRoute(){ 
    .... 
    Route=insertedRoute; 
} 

insertedRoute.LocationInRoute.Add(lInRoute); 
} 
相关问题