[英]Entity Framework issue when saving an entity object
方案:Intranet應用程序。 Windows身份驗證。 EF 6.1.3。 數據庫:SQL Server Compact Edition和MS Access。 VS Studio 2013。
該解決方案包含3個項目:
EnqueteWeb.UI-ASP.NET Web應用程序; EnqueteWeb.Dominio-應用程序域的類庫; ControleDeAcessoGeral-類庫,用於獲取從Active Directory登錄的用戶的數據,並包括/更新/刪除/列出一些對應用程序執行某些特殊操作的用戶。 由於對該應用程序的訪問控制基於SQL Server Compact Edition數據庫,因此我在ControleDeAcessoGeral中安裝了EntityFramework。 我想在該項目的某個類中擁有與用戶有關的所有方法。 所以我做到了。
這個ControleDeAcessoGeral項目的定義如下:
Aplicacao
-Corp.cs(處理Active Directory內容的方法)
-UsuariosApp.cs(處理SQL Server CE數據庫的方法)
語境
-DBControleDeAcesso.cs(定義上下文)
-InicializaControleDeAcesso.cs(將初始數據填充到DBControleDeAcesso數據庫中)
蟲
-Perfil.cs(用戶可以在應用程序上擁有的配置文件)
-Usuarios.cs(可能會對應用執行某些操作的用戶)
-UsuarioAD.cs(Active Directory用戶及其數據)
DBControleDeAcesso.cs類具有以下代碼:
using ControleDeAcessoGeral.Models.Entidades;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
namespace ControleDeAcessoGeral.Models.Contexto
{
public class DBControleDeAcesso : DbContext
{
public DBControleDeAcesso() : base("ControleDeAcessoContext") { }
public DbSet<Perfil> Perfis { get; set; }
public DbSet<Usuario> Usuarios { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
}
實體類如下:
使用System.Collections.Generic; 使用System.ComponentModel.DataAnnotations;
namespace ControleDeAcessoGeral.Models.Entidades
{
public class Usuario
{
[Key]
public string Logon { get; set; }
public string Nome { get; set; }
[Display(Name="Órgão")]
public string Orgao { get; set; }
public string Email { get; set; }
[StringLength(maximumLength: 4)]
public string Depto { get; set; }
[Display(Name = "Perfis")]
public virtual List<Perfil> Perfis { get; set; }
public Usuario()
{
this.Perfis = new List<Perfil>();
}
}
}
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace ControleDeAcessoGeral.Models.Entidades
{
public class Perfil
{
[Key]
public int Id { get; set; }
[Required(ErrorMessage = "Por favor, informe o NOME DO perfil.")]
[StringLength(maximumLength: 25)]
public string Nome { get; set; }
[StringLength(maximumLength: 255)]
[Display(Name = "Descrição")]
public string Descricao { get; set; }
public virtual List<Usuario> Usuarios { get; set; }
public Perfil()
{
this.Usuarios = new List<Usuario>();
}
}
}
而且,UsuariosApp.cs類如下所示(為簡潔起見,我僅顯示與該問題有關的方法):
using ControleDeAcessoGeral.Models.Contexto;
using ControleDeAcessoGeral.Models.Entidades;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
namespace ControleDeAcessoGeral.Models.Aplicacao
{
public class UsuariosApp
{
private DBControleDeAcesso db { get; set; }
public UsuariosApp()
{
db = new DBControleDeAcesso();
}
public void SalvarUsuario(Usuario usuario)
{
db.Usuarios.Add(usuario);
db.SaveChanges();
}
public Perfil LocalizarPerfil(int id)
{
return db.Perfis.Find(id);
}
}
}
嘗試在SQL Server CE數據庫中保存用戶(Usuarios.cs)的操作在AdministracaoController中,並且具有以下代碼:
using ControleDeAcessoGeral.Models.Aplicacao;
using ControleDeAcessoGeral.Models.Entidades;
using EnqueteWeb.UI.Models;
using EnqueteWeb.UI.ViewModels;
using System.Linq;
using System.Web.Mvc;
namespace EnqueteWeb.UI.Controllers
{
public class AdministracaoController : Controller
{
[HttpPost]
public ActionResult CriarUsuarioNaApp(UsuarioViewModel model)
{
foreach (var item in model.PerfisSelecionados)
{
Perfil perfil = new UsuariosApp().LocalizarPerfil(item);
model.Usuario.Perfis.Add(perfil);
}
if (ModelState.IsValid)
{
new UsuariosApp().SalvarUsuario(model.Usuario);
return RedirectToAction("Usuarios");
}
return View(model);
}
}
}
因此,當調用此動作CriarUsuarioNaApp並運行方法SalvarUsuario(model.Usuario)時 ,會發生以下錯誤:
一個IEntityChangeTracker的多個實例不能引用一個實體對象
我已經在網上閱讀了一些有關此的內容,但不幸的是,我仍然無法使其正常工作。
希望有一個睿智善良的靈魂向我展示道路。
感謝您的關注。
保羅·里卡多·費雷拉
該問題是由於您在將所述實體附加到第二個DbContext
實例之前不處置第一個DbContext
實例(從中加載概要文件實體)而DbContext
。
要解決(以及一些其他建議):
UsuariosApp
實現IDisposable
和處置的您的實例DbContext
db
處置時UsuariosApp
UsuariosApp
實例包裝在using
語句中,並將此單個實例用於Perfil
加載和Usuario
保存邏輯 Perfil
加載 ModelState.IsValid
像這樣:
public class UsuariosApp : IDisposable
{
private DBControleDeAcesso db { get; set; }
public UsuariosApp()
{
db = new DBControleDeAcesso();
}
public void SalvarUsuario(Usuario usuario)
{
db.Usuarios.Add(usuario);
db.SaveChanges();
}
public Perfil LocalizarPerfil(int id)
{
return db.Perfis.Find(id);
}
public IEnumerable<Perfil> LocalizarPerfiles( IEnumerable<int> ids )
{
return db.Perfils.Where( p => ids.Contains( p.Id ) )
.ToArray();
}
private bool _disposed = false;
protected virtual void Dispose( bool disposing )
{
if( _disposed )
{
return;
}
if( disposing )
{
db.Dispose();
}
_disposed = true;
}
public void Dispose()
{
Dispose( true );
GC.SuppressFinalize( this );
}
}
public ActionResult CriarUsuarioNaApp( UsuarioViewModel model )
{
// validate model state first
if( ModelState.IsValid )
{
// use single, disposable repo/uow instance
using( var uapp = new UsuariosApp() )
{
// get all profiles in a single call, no loop required
var perfils = uapp.LocalizarPerfiles( model.PerfisSelecionados );
model.Usuario.Perfis.AddRange( perfils );
uapp.SalvarUsuario( model.Usuario );
}
return RedirectToAction( "Usuarios" );
}
return View( model );
}
讓我知道這是否不能解決您的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.