Nhiều thực thể được thêm vào có thể có cùng một khóa chính


81

Đây là mô hình của tôi về 3 thực thể: Route, Location và LocationInRoute.
mô hình

phương thức sau không thành công và nhận được ngoại lệ khi cam kết nó:

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

Khi làm:

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

Tôi đã nhận:

Không thể xác định điểm cuối chính của mối quan hệ 'SimTaskModel.FK_T_STF_SUB_LOCATION_IN_ROUTE_T_STF_LOCATION_location_id'. Nhiều thực thể được thêm vào có thể có cùng một khóa chính.

Khi tách cam kết và chèn vào các methos - nó hoạt động:

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

Tôi muốn gọi commit một lần và bên ngoài phương thức. Tại sao nó không thành công trong ví dụ đầu tiên và ngoại lệ này có nghĩa là gì?


9
@Ladislav Mrnka: Tôi không có sếp và đây là dự án của tôi. Tôi thực sự không biết bạn có ấn tượng ở đâu mà tôi ngay lập tức hỏi trên SO. Bạn không phải là người duy nhất sử dụng máy tính cả ngày. Tư vấn miễn phí? ai đó cung cấp cho bất cứ ai đảm bảo cho câu trả lời của mình? Tôi tin rằng đây là một diễn đàn nơi các câu hỏi có thể được đặt ra ở đây và đây là những gì tôi đang làm. Tôi có rất nhiều câu hỏi và tôi tin rằng tôi đã học được một chặng đường dài nhờ diễn đàn này và những người như bạn. Sự tham gia là một sự lựa chọn.
Naor

1
@Ladislav: Tôi chỉ thấy một câu hỏi được hỏi khá hợp lý và hồ sơ của OP cũng không chỉ ra bất cứ điều gì trên đầu.
Henk Holterman

Bạn đang sử dụng cùng một ObjectContext trong toàn bộ phạm vi hoạt động hay mỗi Kho lưu trữ mới sẽ có một ObjectContext riêng?
Akash Kava

@Akash Kava: Tôi đang sử dụng cùng một ObjectContext.
Naor

Câu trả lời:


144

Lỗi do ID khóa ngoại (trái ngược với tham chiếu) không thể khắc phục được. Trong trường hợp của bạn, bạn có một LocationInRole tham chiếu đến một Vị trí có ID bằng 0. Có nhiều Vị trí có ID này.

Vị trí vẫn chưa được gán ID vì chúng chưa được lưu vào cơ sở dữ liệu, đó là khi ID được tạo. Trong ví dụ thứ hai của bạn, Vị trí được lưu trước khi ID của chúng được truy cập, đó là lý do tại sao điều này hoạt động.

Bạn sẽ không thể dựa vào ID vị trí để xác định các mối quan hệ nếu bạn chỉ muốn SaveChanges sau này.

Hoán đổi dòng sau ...

LocationId = locations[i].Id

... vì điều này ...

Location = locations[i]

Các mối quan hệ sau đó sẽ dựa trên các tham chiếu đối tượng không phụ thuộc vào LocationID.


một trong hai người có thể xem bài đăng của tôi và cho tôi biết cách tôi có thể khắc phục nó không, tôi đang gặp vấn đề tương tự: stackoverflow.com/questions/26783934/… Tôi đánh giá cao điều đó!
duxfox--

Tôi nhận được lỗi này khi tôi triển khai để kiểm tra env ... không có trong environemnet dev bất kỳ ý tưởng nào?
Taran

@Taran Nếu mã giống hệt nhau và bạn đang sử dụng cùng một quy trình để kiểm tra trong cả hai môi trường (tôi sẽ kiểm tra những điểm này) thì điều này có vẻ lạ. Có thể bạn chỉ thêm một vị trí duy nhất (theo ví dụ ở đây) trong nhà phát triển? Hãy thử thêm ít nhất hai.
Scott Munro

Vấn đề của tôi có thể là một biến thể của vấn đề này. Tôi đã thêm các đối tượng con vào bộ sưu tập của cha mẹ mà không đặt thuộc tính cha một cách rõ ràng cho các đối tượng con. Tôi đã mong đợi EF giải quyết vấn đề này, nhưng lại nhận được lỗi tương tự như OP cho đến khi tôi đặt thuộc tính cha trên con một cách rõ ràng. Hy vọng điều này sẽ giúp ai đó.
Eric H

4

Trong trường hợp điều này có ích cho người đọc trong tương lai, trong trường hợp của tôi, lỗi này là do khóa ngoại được định cấu hình không chính xác trong cơ sở dữ liệu của tôi (và mô hình được tạo từ DB).

Tôi đã có các bảng:

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

và bảng Grandchild đã vô tình nhận được một khóa ngoại đối với nó là cha mẹ (Con) và nó là ông bà (Cha mẹ). Khi lưu nhiều thực thể Gốc từ mới, tôi đã nhận được lỗi này. Khắc phục là sửa khóa ngoại.


Trong trường hợp của tôi, tôi đã có (ngớ ngẩn) thiết lập khóa chính cơ sở Bảng của tôi giống như cơ sở Bảng Ngoại chính của tôi và Cột Primary Key của tôi giống như Cột nước ngoài chính tôi cúi đầu trong sự xấu hổ Hy vọng điều này sẽ giúp người ..
Dave

3

Gặp phải lỗi tương tự, tôi rất nghi ngờ vấn đề thực sự là định nghĩa của Vị trí. Nói một cách đơn giản, trong EF Code Đầu tiên, tôi cá rằng nó trông như thế này:

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

Nói cách khác, trong Câu hỏi, ParentLocation / ParentLocationId là một tham chiếu đệ quy quay lại bảng này.

ParentLocationId không Nullable. Điều đó có nghĩa là nó sẽ được chèn bằng số 0 và EF sẽ phàn nàn trên Chèn, thay vì khi bạn Di chuyển - mặc dù sự thật là khi Migration chạy, bạn có một bảng EF sẽ không bao giờ cho phép bạn chèn vào.

Cách duy nhất để làm cho một tham chiếu đệ quy trở lại cùng một bảng hoạt động là làm cho tham chiếu đệ quy có giá trị vô hiệu:

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

Lưu ý ?sau int.


Phiên bản cũ (not-nullable) sẽ không hoạt động nếu bạn thực hiện SaveChanges trên vị trí chính trước khi tạo vị trí con?
André Kops

1
Bỏ qua ở trên, tôi là đồ ngốc. Bạn sẽ không thể tạo vị trí đầu tiên.
André Kops

Cardinality là vấn đề. Chính xác.
aclalex

0

Đối với những người tìm kiếm ngoại lệ này:
Trong trường hợp của tôi, nó không đặt được thuộc tính điều hướng bắt buộc.

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

tôi đã có cùng một vấn đề. với kịch bản dưới đây được giải quyết cho tôi. tôi nghĩ bạn phải thay đổi mã của mình chẳng hạn như dưới đây:

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

insertedRoute.LocationInRoute.Add(lInRoute );
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.