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

son*_*tek 22 c# linq-to-entities entity-framework .net-3.5

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

即:

// poco
public class Author
{
   public Guid Id { get; set; }
   public string UserName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

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

所以我有我的业务对象

var author = new Author { UserName="foo", Id="Guid thats in the db" };
Run Code Online (Sandbox Code Playgroud)

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

var dbAuthor = new dbAuthor { Id=author.Id, UserName=author.UserName };
entities.Attach(dbAuthor);
entities.SaveChanges();
Run Code Online (Sandbox Code Playgroud)

但这给了我以下错误:

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

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

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

Ale*_*mes 15

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

ctx.AttachTo("EntitySet", entity);
Run Code Online (Sandbox Code Playgroud)

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

第一个选项允许您编写:

ctx.AttachToDefault(entity);
Run Code Online (Sandbox Code Playgroud)

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

第二个选项允许您编写:

ctx.EntitySet.Attach(entity);
Run Code Online (Sandbox Code Playgroud)

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

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

希望这可以帮助

亚历克斯


Qui*_*son 13

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

entities.AttachTo("Authors", dbAuthor);
Run Code Online (Sandbox Code Playgroud)

"Authors"你的实际实体集名称在哪里?

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

entities.AddToAuthors(dbAuthor);
Run Code Online (Sandbox Code Playgroud)

这应该是:

public void AddToAuthors(Authors authors)
{
    base.AddObject("Authors", authors);
}
Run Code Online (Sandbox Code Playgroud)

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

  • 这似乎有效,但随后我在每个地方都有"魔术字符串",如果我重命名实体集,我的所有代码都会破坏.有一个更好的方法吗? (4认同)

seb*_*mez 5

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

entities.AttachTo(entities.CreateObjectSet<T>().EntitySet.Name, entity);
Run Code Online (Sandbox Code Playgroud)