如何附加不是来自数据库的Entity Framework对象?

我完全分离了我的Entity Framework对象和我的POCO对象,我只是来回翻译它们……

即:

// poco public class Author { public Guid Id { get; set; } public string UserName { get; set; } } 

然后我有一个EF对象“作者”具有相同的属性..

所以我有我的业务对象

 var author = new Author { UserName="foo", Id="Guid thats in the db" }; 

我想保存此对象,所以我执行以下操作:

 var dbAuthor = new dbAuthor { Id=author.Id, UserName=author.UserName }; entities.Attach(dbAuthor); entities.SaveChanges(); 

但这给了我以下错误:

具有null EntityKey值的对象无法附加到对象上下文。

编辑:看起来我必须使用entities.AttachTo(“作者”,dbAuthor); 没有EntityKey附加,但后来我有硬编码的魔术字符串,如果我改变我的实体集名称将破坏我不会有任何编译时检查…有没有一种方法可以附加,保持编译时间检查?

我希望我能够做到这一点,因为硬编码字符串会导致编译时间validation失败=)

您是否尝试过使用AttachTo并指定实体集?

 entities.AttachTo("Authors", dbAuthor); 

其中"Authors"将是您的实际实体集名称。

编辑:
是的,有更好的方法(应该有)。 设计人员应该为ObjectContext生成“添加”方法 ,转换为上面的调用..所以你应该能够做到:

 entities.AddToAuthors(dbAuthor); 

这应该是:

 public void AddToAuthors(Authors authors) { base.AddObject("Authors", authors); } 

在whateverobjectcontext.designer.cs文件中定义。

刚看到这个。 如果你想Attach()到ObjectContext,即说服entity framework已经存在数据库中的实体,并且你想避免使用魔术字符串,即

 ctx.AttachTo("EntitySet", entity); 

您可以尝试基于扩展方法的两种可能性,这两种方法都可以让生活变得更加可以忍受。

第一个选项允许您编写:

 ctx.AttachToDefault(entity); 

并在此处介绍: 技巧13 – 如何以简单的方式附加实体

第二个选项允许您编写:

 ctx.EntitySet.Attach(entity); 

并在此处介绍: 技巧16 – 今天如何模仿.NET 4.0的ObjectSet

正如您所看到的,两者都非常易于使用并完全避免使用字符串。

希望这可以帮助

亚历克斯

如果您不想使用EntitySet名称编写字符串,请尝试此操作

 entities.AttachTo(entities.CreateObjectSet().EntitySet.Name, entity); 

如果您不知道要对哪个实体进行操作,则可以采用以下方法:

 string className = entityObject.GetType().Name; var container = _DbContext.MetadataWorkspace.GetEntityContainer(_DbContext.DefaultContainerName, DataSpace.CSpace); string setName = (from meta in container.BaseEntitySets where meta.ElementType.Name == className select meta.Name).First(); _DbContext.AttachTo(setName, entityObject); 

你能试试吗?

 entities.AddToAuthors(dbAuthor); 

为了我,

 Context.Authors.AddObject(new Author()) 

工作得很好。 想知道我是否遗漏了什么? 或者这不是正确的方法?