2010-07-17 31 views
5

Gần đây, chúng tôi đã nâng cấp phần mềm của chúng tôi lên .NET 4.0 và EF 4.0 (không có các thực thể tự theo dõi) (trước đây là .NET 3.5 SP1). Bây giờ một ngoại lệ mới được nêu ra trong mã làm việc trước đây, mà chúng ta không hiểu.EntityFramework 4.0: InvalidOperationExeception: Ràng buộc đa dạng vi phạm

Chúng tôi có một thực thể được gọi là Thường trú và một thực thể khác gọi là ResidentExtension, mở rộng thực thể Cư trú đã lớn với mối quan hệ 1 đến (0/1). Mã C# sau đây tạo ra một thực thể mới trong ứng dụng của chúng tôi:

Residents resident = new Residents() 
    { 
     IsNewResident = true, 
     ResidentImage = Settings.Default.ResidentCardDefaultMaleImage, 
     IsActive = true, 
     ResidentCanBeDeleted = true, 
     ResidentExtensions = new ResidentExtensions(), 
     ResidentMasterDataState = EvoState.Error, 
     ResidentBasicDataState = EvoState.Error, 
     ResidentBenefactorsDataState = EvoState.Error, 
    }; 

Trường hợp ngoại lệ sau đây được nêu ra ngay sau khi tuyên bố này:

Multiplicity hạn chế vi phạm. Vai trò 'ResidentExtensions' của mối quan hệ VOCURA.EntityDataModels.EvocuraCarehomeManagementEntityModel.FK_ResidentExtensions_Residents 'có bội số 1 hoặc 0..1.

Nó xảy ra trong setter của mã được tạo:

[XmlIgnoreAttribute()] 
    [SoapIgnoreAttribute()] 
    [DataMemberAttribute()] 
    [EdmRelationshipNavigationPropertyAttribute("EVOCURA.EntityDataModels.EvocuraCarehomeManagementEntityModel", "FK_ResidentExtensions_Residents", "ResidentExtensions")] 
    public ResidentExtensions ResidentExtensions 
    { 
     get 
     { 
      return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<ResidentExtensions>("EVOCURA.EntityDataModels.EvocuraCarehomeManagementEntityModel.FK_ResidentExtensions_Residents", "ResidentExtensions").Value; 
     } 
     set 
     { 
      ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<ResidentExtensions>("EVOCURA.EntityDataModels.EvocuraCarehomeManagementEntityModel.FK_ResidentExtensions_Residents", "ResidentExtensions").Value = value; 
     } 
    } 

Giải pháp duy nhất tôi đã tìm thấy chưa là để gửi đơn vị thường trú mà không mở rộng đầu tiên, và sau này, tạo ra một ResidentExtension với thiết lập khóa ngoài (ResidentID) và thêm nó vào ngữ cảnh và gửi lại. Nhưng đây không phải là cách nó hoạt động trước đây.

Có ai biết cách làm cho công việc này trở lại theo cách cũ không?

+0

Jan, bạn đã bao giờ giải quyết vấn đề này theo cách bạn muốn nó hoạt động chưa? –

+0

Thật không may là không. Vẫn sử dụng giải pháp được tìm thấy trong phần cuối của câu hỏi của tôi, ( – JanW

Trả lời

1
ResidentExtensions = new ResidentExtensions(), 

Tôi nghĩ rằng dòng này không cần thiết chút nào. Bạn đang tạo một đối tượng residentextensions mới không có bất kỳ khóa chính nào và không tồn tại trong cơ sở dữ liệu. Khi bối cảnh cố gắng lưu các nội dung thường trú, nó không thể vì không có thuộc tính nào được đặt, có thể dẫn đến một số ngoại lệ trong cơ sở dữ liệu liên quan đến các trường không có giá trị. Tôi nghĩ rằng những gì bạn cần làm là như sau;

Residents resident = new Residents() 
    { 
     IsNewResident = true, 
     ResidentImage = Settings.Default.ResidentCardDefaultMaleImage, 
     IsActive = true, 
     ResidentCanBeDeleted = true, 
     ResidentMasterDataState = EvoState.Error, 
     ResidentBasicDataState = EvoState.Error, 
     ResidentBenefactorsDataState = EvoState.Error, 
    }; 
//Now you need to either initialize a residentextextensions entity 
// with proper values, or just do not relate it with the resident entity. 
ResidentExtensions temp = new ResidentExtensions(); 
temp.PropertyA = 3; 
//etc. 
resident.ResidentExtensions = temp; 

Tóm tắt, vì thực thể thường trú có quan hệ 1 - 0,1 với ResidentExtensions; nếu bên phải là 0; chỉ cần để lại thuộc tính ResidentExtensions null; nếu không khởi tạo một đối tượng ResidentExtensions thích hợp và thiết lập thuộc tính liên quan.

+0

Theo như tôi biết, trong ví dụ trên, việc gán đối tượng ResidentExtensions cho thuộc tính navigation Residents sẽ tự động đặt khóa ngoài trên đối tượng ResidentExtensions thành khóa chính của đối tượng Cư dân (đó là cách nó hoạt động trong EF <4.0) .Tiện ích mở rộng thường trú được khởi tạo đúng cách, vì nó chỉ chứa khóa ngoại (ResidentID) và các thuộc tính có thể vô hiệu hóa PS: ResidentID là số nguyên với tăng tự động và do đó không tồn tại trước khi gửi thực thể bằng SaveChanges. – JanW

Các vấn đề liên quan