0
나는 뭔가를하려고하는데, 여기에 "데모"이라는 매우 간단한 예가 있습니다. (이 데모는 아무 의미가 없지만 내가 할 노력하고있어 일반적인 아이디어 제공)엔티티 프레임 워크 6.1 첨부되지 않은 경우 확인 후 충돌을 첨부하십시오
은 내가
새로운 컨텍스트를 생성하지 않고 할 수있는 방법이
을 시도 것을 주석을?이 데이터베이스는 SQL 서버에 처음
C# 코드
SQL 스크립트가USE [testing]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[LookupTable](
[LookupId] [int] NOT NULL,
CONSTRAINT [PK_LookupTable] PRIMARY KEY CLUSTERED
(
[LookupId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[MainTable](
[MainId] [int] NOT NULL,
CONSTRAINT [PK_MainTable] PRIMARY KEY CLUSTERED
(
[MainId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[MainTable_LookupTable](
[MainId] [int] NOT NULL,
[LookupId] [int] NOT NULL,
CONSTRAINT [PK_MainTable_LookupTable] PRIMARY KEY CLUSTERED
(
[MainId] ASC,
[LookupId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
INSERT [dbo].[LookupTable] ([LookupId]) VALUES (1)
GO
INSERT [dbo].[MainTable] ([MainId]) VALUES (10)
GO
INSERT [dbo].[MainTable_LookupTable] ([MainId], [LookupId]) VALUES (10, 1)
GO
ALTER TABLE [dbo].[MainTable_LookupTable] WITH CHECK ADD CONSTRAINT [FK_MainTable_LookupTable_LookupTable] FOREIGN KEY([LookupId])
REFERENCES [dbo].[LookupTable] ([LookupId])
GO
ALTER TABLE [dbo].[MainTable_LookupTable] CHECK CONSTRAINT [FK_MainTable_LookupTable_LookupTable]
GO
ALTER TABLE [dbo].[MainTable_LookupTable] WITH CHECK ADD CONSTRAINT [FK_MainTable_LookupTable_MainTable] FOREIGN KEY([MainId])
REFERENCES [dbo].[MainTable] ([MainId])
GO
ALTER TABLE [dbo].[MainTable_LookupTable] CHECK CONSTRAINT [FK_MainTable_LookupTable_MainTable]
GO
솔루션, 내 경우에는,이 코드
for (var i = 1; i < 3; ++i)
{
lookup = db.LookupTables.Local.FirstOrDefault(x => x.LookupId == i);
if (lookup == null)
{
lookup = new edmx.LookupTable() { LookupId = i };
db.LookupTables.Attach(lookup);
}
main.LookupTables.Add(lookup);
}
에게 있습니다
using System;
using System.Data.Entity;
using System.Data.Entity.Core.Objects;
using System.Data.Entity.Infrastructure;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
//remove then add it back, without select from the db
using (var db = new testing())
{
var lookup = new edmx.LookupTable() { LookupId = 1 };
var main = new edmx.MainTable() { MainId = 10 };
main.LookupTables.Add(lookup);
db.LookupTables.Attach(lookup);
db.MainTables.Attach(main);
main.LookupTables.Remove(lookup);
db.SaveChanges();
//imagine this is a loop from n to m and it happen that you have to add back something that you just deleted
lookup = new edmx.LookupTable() { LookupId = 1 };
//crash if nothing
//db.Entry(lookup).State = EntityState.Unchanged; //crash
//db.LookupTables.Attach(lookup); //crash
if (!db.context.IsAttachedTo(lookup))
{
//db.Entry(lookup).State = EntityState.Unchanged; //crash
//db.LookupTables.Attach(lookup); //crash
}
bool isDetached = db.Entry(lookup).State == EntityState.Detached;
if (isDetached)
{
//db.Entry(lookup).State = EntityState.Unchanged; //crash
//db.LookupTables.Attach(lookup); //crash
}
main.LookupTables.Add(lookup);
db.SaveChanges();
}
Console.ReadKey();
}
}
public partial class testing : edmx.testingEntities
{
public testing()
: base()
{
this.Database.Log = x => System.Diagnostics.Debug.Write(x);
}
public ObjectContext context
{
get { return (this as IObjectContextAdapter).ObjectContext; }
}
}
public static class helper
{
public static bool IsAttachedTo(this ObjectContext context, object entity)
{
ObjectStateEntry entry;
if (context.ObjectStateManager.TryGetObjectStateEntry(entity, out entry))
{
return (entry.State != EntityState.Detached);
}
return false;
}
}
}
감사합니다. 제 제안을 사용하여 내 "솔루션"으로 제 질문을 업데이트했습니다. – Fredou