1. ホーム
  2. c#

[解決済み] 複数の追加されたエンティティが同じ主キーを持つ可能性がある

2023-06-20 06:26:29

質問

3つのエンティティからなるモデルです。ルート、ロケーション、LocationInRouteの3つのエンティティです。

を実行すると、以下のメソッドが失敗し、コミット時に例外が発生します。

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

コミットを一度だけ、メソッドの外で呼び出したいと思います。なぜ最初の例では失敗するのでしょうか、またこの例外は何を意味するのでしょうか?

どのように解決するのですか?

このエラーは、解決できない外部キーID(参照ではなく)が原因で発生します。あなたのケースでは、IDが0の場所を参照するLocationInRoleがあります。このIDを持つ場所が複数あります。

IDが生成されるデータベースに保存されていないため、拠点にまだIDが割り当てられていません。2番目の例では、IDにアクセスする前に場所が保存されているため、これが動作します。

SaveChanges を後で行う場合、リレーションシップを定義するために Location ID に依存することはできません。

以下の行を入れ替えてください...

LocationId = locations[i].Id

...このために...

Location = locations[i]

これにより、LocationIDに依存しないオブジェクトの参照に基づいたリレーションシップが実現します。