【问题标题】:Returning Id's from a list in Entity Framework从实体框架中的列表中返回 ID
【发布时间】:2015-10-07 10:35:27
【问题描述】:

我遇到了实体框架的问题,当我执行 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);
}

提前感谢您的帮助。

【问题讨论】:

  • updatedEvents 不是 list,而是 Linq 查询,只要您枚举它就会重新执行。如果你想缓存它以备后用,请将.ToList() 放在updateEvents 赋值行的末尾。

标签: c# entity-framework linq c#-4.0 entity-framework-6


【解决方案1】:

变量updatedEvents 是一个Linq 查询。 Linq 查询不会立即执行。当它在您的代码中执行时,它不会再找到任何更新的对象。在 Linq 查询后面加上.ToList() 会立即执行。

var updatedEvents = updatedObjects.Select(e => (GenerationEvent)e.Entity).ToList();

【讨论】:

    【解决方案2】:

    首先,您的“使用”语句很奇怪。 应该是

    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()。

    我完全希望“updatedEvents”在调用 save-changes 后为空。

    把你的东西……换成类似的东西

    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
    
    }
    

    我怀疑您正在尝试创建某种通用代码来处理任何类型的实体而不指定其类型。您的代码不适合这样做,如果这是您想要做的,我会修改问题以询问您想要实现的目标。但以上是获取已插入实体的 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.
    }
    

    【讨论】:

    • 我遇到的问题是更新和创建新对象(在本例中为 GenerationEvent 对象)的例程又长又复杂,我无法在最后传递列表并更新和在那里添加它们。您查询的代码行,查询上下文本身,它已经修改或添加了对象,并返回一个状态的GenerationEvent类型的所有对象的列表(在Venerik建议的.ToList()之后确定)修改或添加。
    • 好的...对您的工作感兴趣,您能解释更多...我知道您已经解决了。只是想了解为什么?我的意思是你为什么要这样做......,我看到你对一个名为 GenerationEvent 的实体感兴趣,它显然已经更新并添加了一个子例程......你想要它们。我只是将它们添加到例程中的“内部列表”中......然后它们将在调用 savechanges 时使用您想要的 id 进行更新。那怎么行不通。它不那么复杂。
    • 是的,它有点奇怪。他们完全改变了系统的架构方式,同时增加了一大堆额外的功能。以前系统从 Web 服务获取和输入,并将事件详细信息添加或更新到本地数据库,然后实体对象的部分类具有生成复杂 XML 文档的方法,然后将其通过 ftp 传输到其他地方。我被要求现在将不同的文档发送到不同的位置,并且架构师已指定使用两个服务之间的服务总线分离此处理。本来会以不同的方式做的!
    猜你喜欢
    • 1970-01-01
    • 2014-03-02
    • 2015-05-14
    • 2015-07-17
    • 1970-01-01
    • 1970-01-01
    • 2014-02-19
    • 2016-02-21
    • 2023-01-08
    相关资源
    最近更新 更多