多个添加的实体可能具有相同的主键

发布于 2024-11-07 18:32:38 字数 2904 浏览 0 评论 0原文

这是我的 3 个实体模型:路线、位置和 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_LOCATION_location_id”关系的主体端。多个添加的实体可能具有相同的主键。

当分割提交并插入到方法中时 - 它有效:

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

我想在方法之外调用一次提交。为什么它在第一个示例中失败?这个异常意味着什么?

Here is my model of 3 entities: Route, Location and LocationInRoute.
model

the following method fails and get exception when commit it:

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

When doing:

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

I got:

Unable to determine the principal end of the 'SimTaskModel.FK_T_STF_SUB_LOCATION_IN_ROUTE_T_STF_LOCATION_location_id' relationship. Multiple added entities may have the same primary key.

When splitting the commit and insert in into the methos - it works:

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

I would like to call commit once and outside the method. Why it fails in the first example and what does this exception means?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

痴梦一场 2024-11-14 18:32:38

该错误是由无法解析的外键 ID(而不是引用)引起的。在您的例子中,您有一个 LocationInRole 引用 ID 为 0 的位置。有多个具有此 ID 的位置。

尚未为位置分配 ID,因为在生成 ID 时它们尚未保存到数据库中。在第二个示例中,位置会在访问其 ID 之前保存,这就是其有效的原因。

如果您只想稍后保存更改,您将无法依赖位置 ID 来定义关系。

交换以下行...

LocationId = locations[i].Id

...为此...

Location = locations[i]

然后关系将基于不依赖于 LocationID 的对象引用。

The error is caused by a foreign key ID (as opposed to a reference) which cannot be resolved. In your case, you have a LocationInRole that references a Location with an ID of 0. There are multiple Locations with this ID.

The Locations have not yet been assigned an ID because they have not yet been saved to the database which is when the ID is generated. In your second example, the Locations are saved before their IDs are accessed which is why this works.

You will not be able to rely on the Location IDs to define the relationships if you want to SaveChanges only later.

Swap the following line...

LocationId = locations[i].Id

...for this...

Location = locations[i]

The relationships will then be based on object references which are not dependent on the LocationIDs.

掩于岁月 2024-11-14 18:32:38

如果这对未来的读者有任何用处,就我而言,此错误是由于我的数据库(以及从数据库生成的模型)中外键配置不正确造成的。

我有表:

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

孙表无意中收到了一个外键,直到它的父表(子表)和祖父母表(父表)。在从新保存多个父实体时,我收到此错误。修复已更正外键。

In case this is of any use to future readers, in my case this error was due to an incorrectly configured foreign key in my database (and model generated from DB).

I had tables:

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

and the Grandchild table had inadvertently received a foreign key up to it's parent (Child) and it's grandparent (Parent). On saving multiple Parent entities from new, I received this error. Fix has been to correct the foreign key.

柒七 2024-11-14 18:32:38

遇到同样的错误后,我高度怀疑实际问题是位置的定义。简而言之,在 EF Code First 中,我打赌它看起来像这样:

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

换句话说,在问题中,ParentLocation/ParentLocationId 是对此表的递归引用。

ParentLocationId 不可为 Null。这意味着它将用 0 插入,并且 EF 将在插入时抱怨,而不是在您迁移时抱怨 - 即使事实是一旦迁移运行,您就有一个表 EF 永远不会让您插入。

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

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

请注意 int 后面的 ?

Having run into the same error I highly suspect the actual issue was the definition of Location. Put simply, in EF Code First I bet it looked like this:

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

In other words, in the Question, ParentLocation/ParentLocationId are a recursive reference back to this table.

The ParentLocationId is not Nullable. That means it's going to be inserted with a 0, and EF will complain on Insert, rather than when you Migrate - even though the truth is once that Migration runs you have a table EF will never let you insert into.

The only way to make a recursive reference back to the same table work is to make the recursive reference nullable:

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

Note the ? after the int.

大姐,你呐 2024-11-14 18:32:38

对于那些寻找此异常的人:
就我而言,它无法设置所需的导航属性。

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

For those searching for this exception:
In my case, it was failing to set a required navigation property.

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
找回味觉 2024-11-14 18:32:38

我有同样的问题。下面的场景为我解决了。
我认为你必须更改你的代码,如下所示:

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

insertedRoute.LocationInRoute.Add(lInRoute );
}

i had same problem. with below scenario solved for me.
i think you must change your code such as below:

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

insertedRoute.LocationInRoute.Add(lInRoute );
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文