【发布时间】:2018-02-05 02:11:34
【问题描述】:
基本上,我正在处理多对多关系:
+-------------+ +-----------------+ +---------------------------+
| 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)
【问题讨论】:
-
难以阅读,但我认为
dbContext<T>意味着您有多个上下文和更改跟踪器,这会导致现有对象被视为新对象。您的存储库模式实现已损坏。
标签: c# entity-framework entity-framework-6