C# 返回Id';从实体框架中的列表中删除

C# 返回Id';从实体框架中的列表中删除,c#,entity-framework,linq,c#-4.0,entity-framework-6,C#,Entity Framework,Linq,C# 4.0,Entity Framework 6,我对Entity Framework有一个问题,当我执行SaveChanges时,上下文中有很多与之关联的对象,一些对象被更新,一些被添加,之后我想使用所有这些项目的Id(添加项目的Id仅在数据库中插入时分配)。保存更改后,所有对象的列表为空 我在网站上看到过保存后更新对象的示例,因此我怀疑这可能是我首先获得对象列表的方式 这是我的密码: // Lots of processing to create or update objects using (var localContext = th

我对Entity Framework有一个问题,当我执行SaveChanges时,上下文中有很多与之关联的对象,一些对象被更新,一些被添加,之后我想使用所有这些项目的Id(添加项目的Id仅在数据库中插入时分配)。保存更改后,所有对象的列表为空

我在网站上看到过保存后更新对象的示例,因此我怀疑这可能是我首先获得对象列表的方式

这是我的密码:

// Lots of processing to create or update objects 
using (var localContext = this.context)
{
    var updatedObjects = localContext.ChangeTracker.Entries().Where(e => e.Entity is GenerationEvent && (e.State == EntityState.Modified || e.State == EntityState.Added));
    var updatedEvents = updatedObjects.Select(e => (GenerationEvent)e.Entity);

    // The list has 5 items in at this point
    localContext.SaveChanges();

    // This list is now empty
    DoSomethingWithList(updatedEvents);
}

提前感谢您的帮助。

变量
updateEvents
是一个Linq查询。Linq查询不会立即执行。当它在代码中执行时,它将再也找不到任何更新的对象。在Linq查询之后放置
.ToList()
,将立即执行它

var updatedEvents = updatedObjects.Select(e => (GenerationEvent)e.Entity).ToList();
首先,你的“使用”语句很奇怪。 应该是

using (var context = new MyContext()) //passing in optional connection string.
{

}
然后你访问实体的方式看起来很奇怪,或者我不知道你在那里做什么

var updatedObjects = localContext.ChangeTracker.Entries().Where(e => e.Entity is GenerationEvent && (e.State == EntityState.Modified || e.State == EntityState.Added));
var updatedEvents = updatedObjects.Select(e => (GenerationEvent)e.Entity);
似乎您正在询问被视为“添加”或“更新”的所有项目的上下文

然后您接受对上下文的更改。例如SaveChanges()

在调用save changes之后,我完全希望“updateEvents”为空

改变你的东西。。。差不多

using (var context = new MyContext()) //passing in optional connection string.
{
    LIst<EntityType> listOfChangedEntities = //ToDo:either passed in or generated
    context.EntityType.AddRandge(listOfChangedEntities);
    context.SaveChanges();

    //after SaveChanges has been done all the entities in the 
    //listOfChangedEntities will now have there id's

    //for update, fetch the entities... change them and Update them

}
使用(var context=new MyContext())//传入可选的连接字符串。
{
LIst ListofChangedenties=//ToDo:传入或生成
context.EntityType.AddRandge(变更列表);
SaveChanges();
//保存更改完成后,中的所有实体
//更改列表现在将具有以下id
//对于更新,获取实体…更改它们并更新它们
}
我怀疑您试图创建某种通用代码来处理任何类型的实体,而不指定其类型。您的代码不适合这样做,因为它是,如果这是您正在尝试做的,我会修改这个问题,询问您正在尝试实现什么。但以上是获取已插入实体Id的正常方法

您所谈论的另一个例子是,它们使用外键和导航属性来自动关联相关实体,但您的代码与此相去甚远

更新


例行公事

public static DoWork()
{
   var context = new MyContext();  

   List<GenerationEvent > internalEntityType = new List<GenerationEvent ();
   foreach(var item in SomeList)
   {
        var newItemEntity = new GenerationEvent();
        newItemEntity.Name = "Test";
        context.GenerationEvent.Add(newItemEntity);

        //add to internal list
        internalEntityType.Add(newItemEntity )
   }
   context.SaveChanges();

   var first_id = internalEntityType.FirstOrDefault().Id;
   //first_id will not be 0 it will be the Id the database gave it.
}
publicstaticdowork()
{
var context=new MyContext();

List internalEntityType=new List
UpdateEvents
不是一个
列表
,而是一个Linq查询,在您枚举它的任何时候都会重新执行。如果您想缓存它以供以后使用,请放入
.ToList()
updateEvents
赋值行的末尾。我遇到的问题是更新和创建新对象的例程(在本例中为GenerationEvent对象)是很长很复杂的,我无法在最后传递列表并在那里更新和添加它们。您查询的代码行查询已经修改或添加了对象的上下文本身,并返回所有对象的列表(在Venerik建议的.ToList()之后确定)处于修改或添加状态的GenerationEvent类型。好的…对您所做的事情感兴趣,您能解释更多吗…我知道您已经解决了它。只是想了解为什么?我的意思是,您为什么要这样做…,我看到您对名为GenerationEvent的实体感兴趣,该实体显然已更新并添加到子例程中…而您想让他们离开我会把他们加入“内部名单”在例行程序中…当调用savechanges时,它们将被更新为您想要的ID。这怎么会不起作用呢?这样就不那么复杂了。是的,这有点奇怪。它们完全改变了系统的架构,同时添加了大量的额外功能。以前,系统从web服务获取和输入,然后添加或将事件详细信息更新到本地数据库,然后实体对象的部分类有一个方法来生成一个复杂的XML文档,该文档随后被ftp发送到其他地方。我被要求现在将不同的文档发送到不同的位置,架构师已指定使用服务总线在两个se之间分离此处理服务。本来会做得不一样的!