我正在尝试做某事,这是一个“演示”,非常简单的示例。(这个演示没有意义,但它让我大致了解了我正在尝试做的事情)
我评论了我尝试过的内容
有没有办法在不创建新上下文的情况下做到这一点?
这是 sql server 上的数据库
c# 代码
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;
}
}
}
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);
}