相关疑难解决方法(0)

如何阻止Entity Framework尝试保存/插入子对象?

当我用实体框架保存实体时,我自然认为它只会尝试保存指定的实体.但是,它也试图保存该实体的子实体.这导致了各种完整性问题.如何强制EF仅保存我要保存的实体,因此忽略所有子对象?

如果我手动将属性设置为null,则会收到错误"操作失败:由于一个或多个外键属性不可为空,因此无法更改关系." 这非常适得其反,因为我将child对象设置为null,因此EF会将其单独留下.

为什么我不想保存/插入子对象?

由于这是在评论中来回讨论,我将给出一些理由说明为什么我希望我的孩子对象保持独立.

在我正在构建的应用程序中,EF对象模型没有从数据库加载,而是用作我在解析平面文件时填充的数据对象.在子对象的情况下,其中许多引用定义父表的各种属性的查找表.例如,主要实体的地理位置.

由于我自己填充了这些对象,因此EF认为这些是新对象,需要与父对象一起插入.但是,这些定义已经存在,我不想在数据库中创建重复项.我只使用EF对象进行查找并填充主表实体中的外键.

即使子对象是真实数据,我需要首先保存父对象并获得主键或EF似乎只是搞乱了.希望这能给出一些解释.

c# entity-framework

82
推荐指数
5
解决办法
6万
查看次数

Asp.net Identity 2.0更新用户

将用户更改保存到数据库时遇到问题,例如更改人员姓名.我正在使用IdentityModel,它是使用个人身份验证在新的VS2013 Web项目中自动创建的.遗憾的是,除了更改角色之外,模板不允许您更改任何用户信息.我通过谷歌环顾四周,我找不到多少.任何人使用基本身份代码实现更新?

这是我发现的最接近的事情:

更新用户数据 - Asp.net身份

我没有成功合并默认模板.我本周刚刚开始使用Identity,所以可能是我缺乏理解这就是问题所在.

var updatedUser = new ApplicationUser
            {
                Id = model.UserId,
                UserName = model.UserName,
                CustomerId = model.CustomerId,
                Email = model.EmailAddress,
                FirstName = model.FirstName,
                LastName = model.LastName,
                PhoneNumber = model.PhoneNumber,                    
            };

...
var result = await UserManager.UpdateAsync(updatedUser);
Run Code Online (Sandbox Code Playgroud)

我的UserManager是这样创建的:

return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
Run Code Online (Sandbox Code Playgroud)

我在浏览器中收到以下错误:

附加"ApplicationUser"类型的实体失败,因为同一类型的另一个实体已具有相同的主键值.如果图中的任何实体具有冲突的键值,则在使用"附加"方法或将实体的状态设置为"未更改"或"已修改"时,可能会发生这种情况.这可能是因为某些实体是新的并且尚未收到数据库生成的键值.在这种情况下,使用"添加"方法或"已添加"实体状态来跟踪图表,然后根据需要将非新实体的状态设置为"未更改"或"已修改"

谢谢

asp.net asp.net-identity

23
推荐指数
1
解决办法
1万
查看次数

附加类型为"X"的实体失败,因为同一类型的另一个实体

我在我的代码中偶然发现了一个奇怪的错误.以前哪个工作,但现在有时工作.

我正在使用EF6来编辑具有某种关系的实体.不编辑我'附加'它们的关系(参见示例代码).

public void EditA(A ThisIsA, B ThisIsB)
    {
        using (var Context = new LDZ_DEVEntities())
        {
            Context.As.Attach(ThisIsA);

            var b = Context.Bs.FirstOrDefault(x => x.BId == ThisIsB.BId);
            //var b = Context.Bs.Find(ThisIsB.BId);

            if (b != null)
                Context.Bs.Attach(b);
            else
                b = ThisIsB;

            if (b.C != null)
                Context.Cs.Attach(b.C);

            ThisIsA.Bs.Add(b);

            Context.SaveChanges();

        }
    }
Run Code Online (Sandbox Code Playgroud)

我编辑了名字以保持简单.

以下行

Context.Cs.Attach(b.C);
Run Code Online (Sandbox Code Playgroud)

抛出此错误:

附加类型为"C"的实体失败,因为相同类型的另一个实体已具有相同的主键值.如果图中的任何实体具有冲突的键值,则在使用"附加"方法或将实体的状态设置为"未更改"或"已修改"时,可能会发生这种情况.这可能是因为某些实体是新的并且尚未收到数据库生成的键值.在这种情况下,使用"添加"方法或"已添加"实体状态来跟踪图形,然后根据需要将非新实体的状态设置为"未更改"或"已修改".

引入此行是因为所有C实体都是静态实体.我从不想要创建一个C. 如果我删除此行,每次我将A添加到A; 创建了一个C. 这是不可取的.

额外信息:
A有一个B的
B 列表有一个C.

在我的软件中的多个位置调用此EditA()方法.仅在循环(导入)中调用方法时才会出现此错误.在处理第一条记录时没有问题.但是我在第一个记录之后得到了记录中的错误.

我已经阅读了这些问题和答案,但它们并不适合我:

  1. ASP.NET MVC - 附加"MODELNAME"类型的实体失败,因为同一类型的另一个实体已具有相同的主键值

  2. 附加类型的实体失败,因为相同类型的另一个实体已具有相同的主键值

c# entity-framework

17
推荐指数
2
解决办法
6万
查看次数

附加类型的实体失败,因为相同类型的另一个实体已具有相同的主键值

错误消息:附加类型的实体失败,因为同一类型的另一个实体已具有相同的主键值.

问题:如何以类似的方式附加实体,如下面的代码中的AttachActivity方法所示?

我必须假设上面的错误消息的"另一个实体"部分是指存在于内存但超出范围(??)的对象.我注意到这一点,因为我尝试附加的实体类型的DBSet的Local属性返回零.

我有理由相信实体在上下文中不存在,因为我逐步完成代码并在创建时观察上下文.在创建dbcontext之后,实体将立即添加到几行中.

我正在测试这里指定的附加实体:找出实体是否附加到dbContext的最合理方法是什么?

当在visual studio的locals窗口中查看本地时,我看到没有类型为Activity的实体(无论ID),除了我想要附加的实体.

代码按以下顺序执行:Try - > ModifyProject - > AttachActivity

代码在注释行的AttachActivity中失败.

请注意调试注释之间的代码,如果已将任何实体添加到上下文中,则将抛出该代码.

private string AttachActivity(Activity activity)
    {
        string errorMsg = ValidateActivity(activity);  // has no code yet.  No. It does not query db.

        if(String.IsNullOrEmpty(errorMsg))
        {
            // debug 
            var state = db.Entry(activity).State; // Detached
            int activityCount = db.Activities.Local.Count;
            int projectCount = db.Activities.Local.Count;

            if (activityCount > 0 || projectCount > 0)
                throw new Exception("objects exist in dbcontext");
            // end debug
            if (activity.ID == 0)
                db.Activities.Add(activity);
            else
            {
                db.Activities.Attach(activity); …
Run Code Online (Sandbox Code Playgroud)

.net c# entity-framework

8
推荐指数
2
解决办法
2万
查看次数

更新EF 6中的现有数据会引发异常 - "...相同类型的实体已具有相同的主键值".

我正在尝试使用Entity Framework 6更新记录,代码优先,没有流畅的映射或像Automapper这样的工具.

entity(Employee)具有与之关联的其他复合属性,如Addreess(collection),Department

它也是从一个名为的基础继承的 User

save方法如下,_dbContext作为DbConext实现

        public bool UpdateEmployee(Employee employee)
        {
            var entity = _dbContext.Employees.Where(c => c.Id == employee.Id).AsQueryable().FirstOrDefault();
            if (entity == null)
            {
                _dbContext.Employees.Add(employee);
            }
            else
            {
                _dbContext.Entry(employee).State = EntityState.Modified; // <- Exception raised here
                _dbContext.Employees.Attach(employee);

            }

            return _dbContext.SaveChanges() > 0;

        }
Run Code Online (Sandbox Code Playgroud)

我一直收到错误:

附加类型的实体失败,因为相同类型的另一个实体已具有相同的主键值.如果图中的任何实体具有冲突的键值,则在使用"附加"方法或将实体的状态设置为"未更改"或"已修改"时,可能会发生这种情况.这可能是因为某些实体是新的并且尚未收到数据库生成的键值.在这种情况下,使用"添加"方法或"已添加"实体状态来跟踪图形,然后根据需要将非新实体的状态设置为"未更改"或"已修改".

我尝试过以下方法:

  1. 在设置之前附加 EntityState.Modified
  2. 添加AsNoTracking()查询对象是否存在(没有例外,但DB没有更新) - /sf/answers/1625960101/
  3. 使用基本实体_dbContext.Users而不是Employee实体进行保存 - /sf/answers/1790294411/

现在这些都不适合我.

对于那些不能在我的情况下工作的解决方案,我有什么问题?

c# entity-framework entity-framework-6

7
推荐指数
2
解决办法
2万
查看次数

附加类型的实体失败,因为相同类型的另一个实体已具有相同的主键值.

让我快速描述我的问题.

我有5个客户的5个数据库,每个数据库都有一个名为SubnetSettings的表.

我已经创建了一个下拉列表来选择一个客户,并将显示属于所选客户的SubnetSetting表,并允许我创建,编辑和删除.

我可以创建,删除没有问题,但当我想编辑数据时,它会带来错误:

'/ TMS'应用程序中的服务器错误.

附加"CFS.Domain.Entities.SubnetSettings"类型的实体失败,因为同一类型的另一个实体已具有相同的主键值.如果图中的任何实体具有冲突的键值,则在使用"附加"方法或将实体的状态设置为"未更改"或"已修改"时,可能会发生这种情况.这可能是因为某些实体是新的并且尚未收到数据库生成的键值.在这种情况下,使用"添加"方法或"已添加"实体状态来跟踪图形,然后根据需要将非新实体的状态设置为"未更改"或"已修改".

这是我的控制器中的编辑

    // GET: /SubnetSettings/Edit1/5   
    public ActionResult Edit1(short? id)  
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        SubnetSettings subnetsettings = detailView.SubnetSettings.SingleOrDefault(t => t.Id == id); 
        if (subnetsettings == null)
        {
            return HttpNotFound();
        } 
        return View(subnetsettings);
    }


    // POST: /SubnetSettings/Edit1/5   
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit1([Bind(Include = "Id,Name,fDialUp,fPulse,fUseExternalGSMModem,fGsmDialUp,bUploadMethodId")] SubnetSettings subnetsettings)
    {
        if (ModelState.IsValid)
            {
                templateDb2.Save(subnetsettings);   
                return RedirectToAction("Index");
            }
        return View(subnetsettings);
    }
Run Code Online (Sandbox Code Playgroud)

这是EF中的Save方法

     public SubnetSettings Save(SubnetSettings …
Run Code Online (Sandbox Code Playgroud)

c# model-view-controller entity-framework primary-key

6
推荐指数
1
解决办法
2万
查看次数

更新数据库条目MVC实体框架

我有一个支付模型,其'状态'布尔值默认为false.付款完成后,我需要将特定付款的"状态"更新为true.

这是我一直试图用来更改特定数据库条目的代码,但它只是没有改变它.我究竟做错了什么?

Payment payment = new Payment();
payment = db.Payments.Find(orderId);
db.Entry(payment).State = EntityState.Modified;
payment.Status = true;
db.SaveChanges();
Run Code Online (Sandbox Code Playgroud)

谢谢!

这就是最终的工作:

using (var con = new ApplicationDbContext())
{
    payment = con.Payments.First(x => x.Id == orderId);
    payment.Status = true;

    con.Payments.Attach(payment);
    var entry = con.Entry(payment);
    entry.Property(e => e.Status).IsModified = true;
    con.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)

asp.net-mvc entity-framework

6
推荐指数
1
解决办法
4万
查看次数

使用asp.net标识更新用户角色

我有以下问题.使用下面的代码更改用户的当前角色时,我收到如下消息的异常:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public virtual ActionResult Edit(User user, string role)
    {
        if (ModelState.IsValid)
        {
            var oldUser = DB.Users.SingleOrDefault(u => u.Id == user.Id);
            var oldRoleId = oldUser.Roles.SingleOrDefault().RoleId;
            var oldRoleName = DB.Roles.SingleOrDefault(r => r.Id == oldRoleId).Name;
            if (oldRoleName != role)
            {
                Manager.RemoveFromRole(user.Id, oldRoleName);
                Manager.AddToRole(user.Id, role);
            }
            DB.Entry(user).State = EntityState.Modified;

            return RedirectToAction(MVC.User.Index());
        }
        return View(user);
    }
Run Code Online (Sandbox Code Playgroud)

附加"Models.Entities.User"类型的实体失败,因为同一类型的另一个实体已具有相同的主键值.如果图中的任何实体具有冲突的键值,则在使用"附加"方法或将实体的状态设置为"未更改"或"已修改"时,可能会发生这种情况.这可能是因为某些实体是新的并且尚未收到数据库生成的键值.在这种情况下,使用"添加"方法或"已添加"实体状态来跟踪图形,然后根据需要将非新实体的状态设置为"未更改"或"已修改".

有人知道这个问题的一个很好的解决方案吗?

asp.net asp.net-mvc asp.net-mvc-5 asp.net-identity

4
推荐指数
1
解决办法
1万
查看次数

使用AutoMapper,"相同类型的实体已经具有相同的主键值"错误

当我使用AutoMapper时,出现此错误:

附加"MyProject.DAL.User"类型的实体失败,因为同一类型的另一个实体已具有相同的主键值.如果图中的任何实体具有冲突的键值,则在使用"附加"方法或将实体的状态设置为"未更改"或"已修改"时,可能会发生这种情况.这可能是因为某些实体是新的并且尚未收到数据库生成的键值.在这种情况下,使用"添加"方法或"已添加"实体状态来跟踪图形,然后根据需要将非新实体的状态设置为"未更改"或"已修改".

我想从数据库中检索User时将User映射到UserModel.我在UI中更改UserModel属性,然后再将其映射到User并更新它.我的代码在这里:

public UserModel GetUserByUserId(int id)
    {
        var user = db.Users.Where(p => p.UserId == id).FirstOrDefault();
        var userModel = Mapper.Map<UserModel>(user);
        return userModel;
    }

public void Update(UserModel userModel)
    {
        var user = Mapper.Map<User>(userModel);
        db.Entry(user).State = EntityState.Modified;
        db.SaveChanges();
    }
Run Code Online (Sandbox Code Playgroud)

但如果我不使用自动映射器并编写类似下面的代码,它可以正常工作.

public void Update(UserModel userModel)
    {
        updatingUser.Email = userModel.Email;
        updatingUser.FirstName = userModel.FirstName;
        updatingUser.ModifiedDate = DateTime.Now;
        updatingUser.LastName = userModel.LastName;
        updatingUser.Password = userModel.Password;
        updatingUser.UserName = userModel.UserName;

        db.Entry(updatingUser).State = EntityState.Modified;
        db.SaveChanges();
    }
Run Code Online (Sandbox Code Playgroud)

我该怎么办:

c# entity-framework automapper

3
推荐指数
1
解决办法
2万
查看次数

尝试使用通用存储库更新 EF 中的类时出现“附加类型的实体失败...”异常

我正在使用实体框架。我想加载一个实体,对其进行编辑,然后将更改保存回数据库中。但无论我编辑的是外键属性还是简单属性,EF 都会给出以下错误:

附加“ClassX”类型的实体失败,因为同一类型的另一个实体已具有相同的主键值。如果图表中的任何实体具有冲突的键值,则在使用“附加”方法或将实体的状态设置为“未更改”或“已修改”时,可能会发生这种情况。这可能是因为某些实体是新的,尚未收到数据库生成的键值。在这种情况下,使用“添加”方法或“已添加”实体状态来跟踪图形,然后根据需要将非新实体的状态设置为“未更改”或“已修改”。

请注意,这ClassX不是我要更新的类的直接虚拟属性,而是我的类具有导航属性的其他一些类中的虚拟属性。

我读过一些 相关问题。但我真的不知道应该如何将它们应用到我自己的问题上,因为我使用的是下面发布的通用存储库。

public class GenericRepository<T>  where T : class
{
    private EFDbContext context = new EFDbContext();
    public IEnumerable<T> GetAll()
    {
        return context.Set<T>();
    }
    public void Insert(T entity)
    {
        context.Set<T>().Add(entity);
        context.SaveChanges();
    }
    public void Update(T entity)
    {
        context.Entry(entity).State = System.Data.Entity.EntityState.Modified;
        context.SaveChanges();
    }
 //removed for brevity
}
Run Code Online (Sandbox Code Playgroud)

我遇到了另一个与虚拟属性相关的问题,建议我使用ViewModels对象到对象映射。

据我所知,有3个选择:

  1. 使用ViewModels对象到对象的映射。我不会选择这个,这真的很痛苦,因为 O2O 映射库有很多错误。
  2. 以某种方式使用reference. 但我不能这样做,因为存储库是通用的。也许我应该使用反射 API 来实现这一点?
  3. 删除所有虚拟属性。这实际上是一种选择,因为他们制造的问题比解决的问题还要多。

谁能解释一下为什么会出现这个问题以及解决它的最简单方法是什么?

c# entity-framework ef-code-first entity-framework-6

2
推荐指数
1
解决办法
4913
查看次数