これまで数回、私たちのシステムで数回実行しましたが、見つかりませんでした推論...EF 6:multipleを挿入する - 1つ以上の外部キーのプロパティがnullでないために関係を変更できませんでした
本質的に私は連絡先を持っており、連絡先にはnullable PhoneNumberがあります。
コードは、ビューモデルのリストをループし、それらをデータモデルにマップし、(すべてのモデルがマップされた後に)SaveChanges()を呼び出します。
テストデータには電話番号のデータが複製されています。テストデータを変更して連絡先ごとに異なる電話番号を設定すると、すべてがうまく保存されます。
ここでは、私が行っていることを単純なサンプルで説明します。
class Program
{
static void Main(string[] args)
{
TestWeirdEDMXIssue();
Console.ReadLine();
}
static void TestWeirdEDMXIssue()
{
List<dynamic> works = new List<dynamic>
{
new { FirstName = "Fred", LastName = "Snider", PhoneNumber = "888-888-8881", CountryID = 1 },
new { FirstName = "Ted", LastName = "Snider", PhoneNumber = "888-888-8882", CountryID = 1 },
new { FirstName = "Mike", LastName = "Snider", PhoneNumber = "888-888-8883", CountryID = 1 },
new { FirstName = "Tim", LastName = "Snider", PhoneNumber = "888-888-8884", CountryID = 1 },
new { FirstName = "Todd", LastName = "Snider", PhoneNumber = "888-888-8885", CountryID = 1 },
new { FirstName = "Terry", LastName = "Snider", PhoneNumber = "888-888-8886", CountryID = 1 }
};
List<dynamic> broken = new List<dynamic>
{
new { FirstName = "Fred", LastName = "Snider", PhoneNumber = "888-888-8888", CountryID = 1 },
new { FirstName = "Ted", LastName = "Snider", PhoneNumber = "888-888-8888", CountryID = 1 },
new { FirstName = "Mike", LastName = "Snider", PhoneNumber = "888-888-8888", CountryID = 1 },
new { FirstName = "Tim", LastName = "Snider", PhoneNumber = "888-888-8888", CountryID = 1 },
new { FirstName = "Todd", LastName = "Snider", PhoneNumber = "888-888-8888", CountryID = 1 },
new { FirstName = "Terry", LastName = "Snider", PhoneNumber = "888-888-8888", CountryID = 1 }
};
TestWeirdEDMXIssueSave(works); //Completes with "Success!"
TestWeirdEDMXIssueSave(broken); //Throws Exception
}
static void TestWeirdEDMXIssueSave(List<dynamic> data)
{
try
{
using (var context = new DBEntities())
{
var creatorID = context.UserProfiles.FirstOrDefault(up => up.Contact.FirstName == "automationtestuser")?.ID ?? Guid.Empty;
foreach (var item in data)
{
var contact = context.Contacts.Create();
context.Contacts.Add(contact);
contact.ID = Guid.NewGuid();
contact.FirstName = item.FirstName;
contact.LastName = item.LastName;
contact.CreationDate = DateTime.Now;
contact.CreatedBy = creatorID;
var phoneNumber = context.PhoneNumbers.Create();
context.PhoneNumbers.Add(phoneNumber);
//PhoneNumber ID is Identity
phoneNumber.CreatedBy = creatorID;
phoneNumber.CreationDate = DateTime.Now;
phoneNumber.TypeID = (int)PhoneNumberTypes.Office;
phoneNumber.Number = item.PhoneNumber;
phoneNumber.CountryID = item.CountryID;
contact.PhoneNumber = phoneNumber;
}
context.SaveChanges();
}
Console.WriteLine("Success!");
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
}
OUTPUT
Success!
System.InvalidOperationException: The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.
at System.Data.Entity.Core.Objects.ObjectContext.PrepareToSaveChanges(SaveOptions options)
at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesInternal(SaveOptions options, Boolean executeInExistingTransaction)
at System.Data.Entity.Core.Objects.ObjectContext.SaveChanges(SaveOptions options)
at System.Data.Entity.Internal.InternalContext.SaveChanges()
at System.Data.Entity.Internal.LazyInternalContext.SaveChanges()
at System.Data.Entity.DbContext.SaveChanges()
...(My Code)...
EDITここ は、表の作成するスクリプトです(SQLが生成され、そのビット醜いそう):
問い合わせ
CREATE TABLE [Common].[Contacts](
[ID] [uniqueidentifier] NOT NULL,
[FirstName] [varchar](25) NOT NULL,
[MiddleInitial] [char](1) NULL,
[LastName] [varchar](50) NOT NULL,
[Title] [varchar](50) NULL,
[Description] [varchar](255) NULL,
[ContactEmailAddress] [varchar](100) NULL,
[ContactPhoneNumberID] [int] NULL,
[ContactFaxNumberID] [int] NULL,
[AddressID] [int] NULL,
[ACHDate] [datetime] NULL,
[CreatedBy] [uniqueidentifier] NOT NULL,
[CreationDate] [datetime] NOT NULL,
[IsMarkedAsDeleted] [bit] NOT NULL,
[Position] [varchar](50) NULL,
[MiddleName] [varchar](50) NULL,
[LastThenFirstName] AS (case when [LastName] IS NULL OR len(rtrim([LastName]))=(0) then [FirstName] when [FirstName] IS NULL OR len(rtrim([FirstName]))=(0) then [LastName] else (rtrim(ltrim([LastName]))+', ')+rtrim(ltrim([FirstName])) end) PERSISTED,
[FirstThenLastName] AS (rtrim(ltrim((isnull([FirstName],'')+' ')+isnull([LastName],'')))) PERSISTED,
[AuthenticatorPin] [int] NULL,
[AuthenticatorCode] [int] NULL,
CONSTRAINT [PK_Contacts] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [Common].[Contacts] ADD CONSTRAINT [DF_Contacts_ID] DEFAULT (newid()) FOR [ID]
GO
ALTER TABLE [Common].[Contacts] ADD CONSTRAINT [DF_Contacts_CreationDate] DEFAULT (getdate()) FOR [CreationDate]
GO
ALTER TABLE [Common].[Contacts] ADD CONSTRAINT [DF_Contacts_IsMarkedAsDeleted] DEFAULT ((0)) FOR [IsMarkedAsDeleted]
GO
ALTER TABLE [Common].[Contacts] WITH CHECK ADD CONSTRAINT [FK_Contacts_AddressID_Addresses_ID] FOREIGN KEY([AddressID])
REFERENCES [Common].[Addresses] ([ID])
GO
ALTER TABLE [Common].[Contacts] CHECK CONSTRAINT [FK_Contacts_AddressID_Addresses_ID]
GO
ALTER TABLE [Common].[Contacts] WITH CHECK ADD CONSTRAINT [FK_Contacts_ContactFaxNumberID_PhoneNumbers_ID] FOREIGN KEY([ContactFaxNumberID])
REFERENCES [Common].[PhoneNumbers] ([ID])
GO
ALTER TABLE [Common].[Contacts] CHECK CONSTRAINT [FK_Contacts_ContactFaxNumberID_PhoneNumbers_ID]
GO
ALTER TABLE [Common].[Contacts] WITH CHECK ADD CONSTRAINT [FK_Contacts_ContactPhoneNumberID_PhoneNumbers_ID] FOREIGN KEY([ContactPhoneNumberID])
REFERENCES [Common].[PhoneNumbers] ([ID])
GO
ALTER TABLE [Common].[Contacts] CHECK CONSTRAINT [FK_Contacts_ContactPhoneNumberID_PhoneNumbers_ID]
GO
ALTER TABLE [Common].[Contacts] WITH CHECK ADD CONSTRAINT [FK_Contacts_CreatedBy_UserProfiles_ID] FOREIGN KEY([CreatedBy])
REFERENCES [Common].[UserProfiles] ([ID])
GO
ALTER TABLE [Common].[Contacts] CHECK CONSTRAINT [FK_Contacts_CreatedBy_UserProfiles_ID]
GO
電話番号
CREATE TABLE [Common].[PhoneNumbers](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Number] [varchar](20) NOT NULL,
[Extension] [varchar](10) NULL,
[TypeID] [int] NOT NULL,
[CountryID] [int] NOT NULL,
[CreatedBy] [uniqueidentifier] NOT NULL,
[CreationDate] [datetime] NOT NULL,
[IsMarkedAsDeleted] [bit] NOT NULL,
CONSTRAINT [PK_PhoneNumbers] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [Common].[PhoneNumbers] ADD CONSTRAINT [DF_PhoneNumbers_CreationDate] DEFAULT (getdate()) FOR [CreationDate]
GO
ALTER TABLE [Common].[PhoneNumbers] ADD CONSTRAINT [DF_PhoneNumbers_IsMarkedAsDeleted] DEFAULT ((0)) FOR [IsMarkedAsDeleted]
GO
ALTER TABLE [Common].[PhoneNumbers] WITH CHECK ADD CONSTRAINT [FK_PhoneNumbers_CountryID_Countries_ID] FOREIGN KEY([CountryID])
REFERENCES [Common].[Countries] ([ID])
GO
ALTER TABLE [Common].[PhoneNumbers] CHECK CONSTRAINT [FK_PhoneNumbers_CountryID_Countries_ID]
GO
ALTER TABLE [Common].[PhoneNumbers] WITH CHECK ADD CONSTRAINT [FK_PhoneNumbers_CreatedBy_UserProfiles_ID] FOREIGN KEY([CreatedBy])
REFERENCES [Common].[UserProfiles] ([ID])
GO
ALTER TABLE [Common].[PhoneNumbers] CHECK CONSTRAINT [FK_PhoneNumbers_CreatedBy_UserProfiles_ID]
GO
ALTER TABLE [Common].[PhoneNumbers] WITH CHECK ADD CONSTRAINT [FK_PhoneNumbers_TypeID_PhoneNumberTypes_ID] FOREIGN KEY([TypeID])
REFERENCES [Common].[PhoneNumberTypes] ([ID])
GO
ALTER TABLE [Common].[PhoneNumbers] CHECK CONSTRAINT [FK_PhoneNumbers_TypeID_PhoneNumberTypes_ID]
GO
'PhoneNumbers'テーブルに重複する電話番号が入力されないようにする' Number'カラムに一意の制約があると仮定します。 'Contact'は整数フィールド' PhoneNumberId'(あるいはおそらく 'PhoneNumber_Id')を持っていますか?そうでなければ、EFはforiegnキーがnullではないことを認識せず、最初に連絡先を挿入しようとしている可能性があります。その後、電話番号 –