我正在处理多种关系,基本上是:
+-------------+ +-----------------+ +---------------------------+
| Redes | | Objetivos | | RedesObjetivos |
+-------------+ +-----------------+ +---------------------------+
| | RedesID | | | ObjetivosID | | | RedesID | ObjetivosID |
+---+---------+ +-----------------+ +---------------------------+
| 1 | | | 1 | | | 1 | | |
+---+---------+ +-----------------+ +---------------------------+
Table Objetivos是一组先前注册的选项。当我的用户尝试注册新的Redes时,他会在Objetivos列表中选择并保存。
此时Objetivos表有8个选项
+------------------+
| Objetivos |
+------------------+
| | ObjetivosID |
+----+-------------+
| 1 | 1 |
+----+-------------+
| 2 | 2 |
+----+-------------+
| 3 | 3 |
+----+-------------+
| 4 | 4 |
+----+-------------+
| 5 | 5 |
+----+-------------+
| 6 | 6 |
+----+-------------+
| 7 | 7 |
+----+-------------+
| 8 | 8 |
+----+-------------+
假设我添加了一个新的Redes并选择了Objetivos 5到8 目前的最终结果是:
+-------------+ +-------------------+ +---------------------------+
| Redes | | Objetivos | | RedesObjetivos |
+-------------+ +-------------------+ +---------------------------+
| | RedesID | | | ObjetivosID | | | RedesID | ObjetivosID |
+---+---------+ +---+---------------+ +---------------------------+
| 1 | 1 | | 1 | 1 | | 1 | 1 | 9 |
+---+---------+ +---+---------------+ +---------------------------+
| 2 | 2 | | 2 | 1 | 10 |
+---+---------------+ +---------------------------+
| 3 | 3 | | 3 | 1 | 11 |
+---+---------------+ +---------------------------+
| 4 | 4 | | 4 | 1 | 12 |
+---+---------------+ +---------------------------+
| 5 | 5 |
+---+---------------+
| 6 | 6 |
+---+---------------+
| 7 | 7 |
+---+---------------+
| 8 | 8 |
+---+---------------+
| 9 | 9 |
+---+---------------+
| 10| 10 |
+---+---------------+
| 11| 11 |
+---+---------------+
| 12| 12 |
+---+---------------+
我想要的结果是:
+-------------+ +-------------------+ +---------------------------+
| Redes | | Objetivos | | RedesObjetivos |
+-------------+ +-------------------+ +---------------------------+
| | RedesID | | | ObjetivosID | | | RedesID | ObjetivosID |
+---+---------+ +---+---------------+ +---------------------------+
| 1 | 1 | | 1 | 1 | | 1 | 1 | 5 |
+---+---------+ +---+---------------+ +---------------------------+
| 2 | 2 | | 2 | 1 | 6 |
+---+---------------+ +---------------------------+
| 3 | 3 | | 3 | 1 | 7 |
+---+---------------+ +---------------------------+
| 4 | 4 | | 4 | 1 | 8 |
+---+---------------+ +---------------------------+
| 5 | 5 |
+---+---------------+
| 6 | 6 |
+---+---------------+
| 7 | 7 |
+---+---------------+
| 8 | 8 |
+---+---------------+
基本上,EF并未确定Objetivos已存在于数据库中并且正在创建新行。我怎样才能正确地向EF表明那些Objetivos已经存在?
我经历了很多关于如何与EF一起工作的搜索,我知道有类似于我的问题,但由于我无法解决他们的问题,我决定发布我的全部场景以获得帮助。
这就是我现在所拥有的:
//DAL Layer
//Interface where a set the basic database methods
public interface IDao<T> where T : class
{
//Save
int Salva(T Modelo);
//Update
int Atualiza(T model);
//Delete
void Exclui(T model);
//GetAll
IEnumerable<T> ObtemTodos();
//GetByID
T ObtemPorId(object id);
IEnumerable<T> Where(Expression<Func<T, bool>> expression);
IEnumerable<T> OrderBy(Expression<System.Func<T, bool>> expression);
}
//Generic context, where i implement the methods in the interface
public partial class dbContext<T> : DbContext where T : class
{
public DbSet<T> DbSet
{
get;
set;
}
public dbContext()
: base("name=dbContext")
{
}
public virtual void ChangeObjectState(object model, EntityState state)
{
((IObjectContextAdapter)this)
.ObjectContext
.ObjectStateManager
.ChangeObjectState(model, state);
}
//Save
public virtual int Salva(T model)
{
this.DbSet.Add(model);
return this.SaveChanges();
}
//Update
public virtual int Atualiza(T model)
{
var entry = this.Entry(model);
if (entry.State == EntityState.Detached)
this.DbSet.Attach(model);
this.ChangeObjectState(model, EntityState.Modified);
return this.SaveChanges();
}
//Delete
public virtual void Exclui(T model)
{
var entry = this.Entry(model);
if (entry.State == EntityState.Detached)
this.DbSet.Attach(model);
this.ChangeObjectState(model, EntityState.Deleted);
this.SaveChanges();
}
//GetAll
public virtual IEnumerable<T> ObtemTodos()
{
return this.DbSet.ToList();
}
//GetByID
public virtual T ObtemPorId(object id)
{
return this.DbSet.Find(id);
}
public virtual IEnumerable<T> Where(Expression<Func<T, bool>> expression)
{
return this.DbSet.Where(expression);
}
public IEnumerable<T> OrderBy(Expression<Func<T, bool>> expression)
{
return this.DbSet.OrderBy(expression);
}
}
//Then the relevant DAO classes where I implement specific database methods if necessary
public class RedesDAO : dbContext<Redes>, IDao<Redes>
{
//Save
public override int Salva(Redes Model)
{
ObjetivosDAO ObjetivosDAO = new ObjetivosDAO();
Model.RedeObjetivos = new List<Objetivos>();
//ObjetivosSelecionados is a List<int> with Ids that relates to user's selected options on my view
//each option relates to an especific Objetivos row that already exist in the database
foreach (int ObjetivoID in Model.ObjetivosSelecionados)
{
//So, with each ID I obtain the whole information for that entity
//by using the ObtemPorId = GetByID method and adding it to models' collection
Objetivos Objetivo = ObjetivosDAO.ObtemPorId(ObjetivoID);
Model.RedeObjetivos.Add(Objetivo);
}
this.DbSet.Add(Model);
return this.SaveChanges();
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Redes>().
HasMany(c => c.RedeObjetivos).
WithMany(p => p.Redes).
Map(
m =>
{
m.MapLeftKey("RedeID");
m.MapRightKey("ObjetivoID");
m.ToTable("RedesObjetivos");
});
}
}
public class ObjetivosDAO : dbContext<Objetivos>, IDao<Objetivos>
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Objetivos>().
HasMany(c => c.Redes).
WithMany(p => p.RedeObjetivos).
Map(
m =>
{
m.MapLeftKey("ObjetivoID");
m.MapRightKey("RedeID");
m.ToTable("RedesObjetivos");
});
}
}
//And my models/tables
public partial class Redes
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int RedeID { get; set; }
[Required]
public ICollection<Objetivos> RedeObjetivos { get; set; }
[NotMapped]
public List<int> ObjetivosSelecionados { get; set; }
}
public partial class Objetivos
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ObjetivoID { get; set; }
[Required]
public ICollection<Redes> Redes { get; set; }
}
请注意,我为保存新Redes而执行的方法是RedesDAO类的覆盖。
//Model = Information that comes from my view
public override int Salva(Redes Model)
答案 0 :(得分:0)
您指定了2个不同的DbContexts,RedesDAO
和ObjetivosDAO
。 EntityFramework的上下文对于两个对象都是不同的,这意味着您的第二个上下文无法看到该对象是从数据库中获取的。
要修复,您可以替换以下行:
Objetivos Objetivo = ObjetivosDAO.ObtemPorId(ObjetivoID);
使用:
Objetivos Objetivo = base.Set<Objetivos>().Find(ObjetivoID);
这可以防止对象被误认为是新的。
作为旁注,除非您有特定的理由将它们分开,否则最好使用单个DbContext类与数据库进行通信。