通用存储库中的更新方法不会更新导航属性

时间:2013-12-05 23:02:59

标签: c# asp.net-mvc entity-framework

我想知道实体框架是否自动跟踪实体的导航属性的更改,并在使用SaveChanges()更新相关实体时更新这些更改。我正在使用通用存储库,工作单元,ninject与MVC 4中的代码第一实体框架5.我有一个具有多对多关系的帖子和标签表。我有一个这种关系的连接表,名为PostTagMap,有两列,Post_id和Tag_id。当我添加一个带有相关标签的新帖子时,新帖子已成功添加到帖子表中,PostTagMap也会保存与此帖子关联的标签。但是,当我尝试编辑/更新帖子及其相关标签时,只会更新帖子的标量属性,而不会更新相关标签。我尝试调试,我发现要更新的post实体确实具有标签导航属性的更新值,但实体框架只生成post表的更新语句而不是PostTagMap。我该怎么做才能更新帖子的标签导航属性。

以下是使用的课程

DBContext类

public class EFDbContext : DbContext
{
    public DbSet<Post> Posts { get; set; }
    public DbSet<Tag> Tags { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Post>()
            .HasMany<Tag>(p => p.Tags)
            .WithMany(u => u.Posts)
            .Map(m =>
            {
                m.ToTable("PostTagMap");
                m.MapLeftKey("Post_id");
                m.MapRightKey("Tag_id");
            });
    }

 }

发布课程

[Table("Post")]
public class Post
{
    public int Id { get; set; }
    public string Title { get; set; }

    public virtual ICollection<Tag> Tags { get; set; }  
}

标记类

[Table("Tag")]
public class Tag
{
    public int Id { get; set; }
    public string Name { get; set; }

    [JsonIgnore] 
    public  ICollection<Post> Posts { get; set; }
}

实现IGenericRepository的通用存储库

public class EFGenericRepository<T> : IGenericRepository<T> where T : class
{
    private DbContext DbContext { get; set; }

    private DbSet<T> DbSet { get; set; }


    public virtual void Add(T newEntity)
    {
        DbSet.Add(newEntity);
    }

    public virtual void Update(T entityToUpdate)
    {
        DbSet.Attach(entityToUpdate);

        DbContext.Entry(entityToUpdate).State = EntityState.Modified;
    }

 }

实施IUnitOfWork的工作单元

public class EfUnitOfWork : IUnitOfWork
{
    private EFDbContext dbContext;

    private IGenericRepository<Post> postRepository;
        private IGenericRepository<Tag> tagRepository;

    public EfUnitOfWork()
        {
            this.dbContext = new EFDbContext();
        }

    public void Commit()
        {
            dbContext.SaveChanges();
        }


    public IGenericRepository<Post> PostRepository
        {
            get
            {
                if (this.postRepository == null)
                {
                    this.postRepository = new EFGenericRepository<Post>(dbContext);
                }

                return postRepository;
            }
        }

    public IGenericRepository<Tag> TagRepository
        {
            get
            {
                if (this.tagRepository == null)
                {
                    this.tagRepository = new EFGenericRepository<Tag>(dbContext);
                }

                return tagRepository;
            }
        }

    private bool disposed = false;

        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    dbContext.Dispose();
                }
            }
            this.disposed = true;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

}

服务层

public class ServiceRepository : IServiceRepository
{
    private readonly IUnitOfWork UoW;

    public ServiceRepository(IUnitOfWork _UoW)
        {
            UoW = _UoW;
        }


    public int AddPost(Post post)
        {
            UoW.PostRepository.Add(post);

            UoW.Commit();

            return post.Id;
        }

    public void EditPost(Post post)
        {
            UoW.PostRepository.Update(post);

            UoW.Commit();
        }

}

管理员控制器

public class AdminController : Controller
{
    private readonly IServiceRepository _serviceRepository;

    public AdminController(IServiceRepository serviceRepository)
    {
        _serviceRepository = serviceRepository;
    }       


[HttpPost, ValidateInput(false)]
    public ContentResult AddPost(Post post)
    {
        string json;

        ModelState.Clear();

        if (TryValidateModel(post))
        {
            var id = _serviceRepository.AddPost(post);

            json = JsonConvert.SerializeObject(new
                                                {
                                                    id = id,
                                                    success = true,
                                                    message = "Post added successfully"
                                                });
        }
        else
        {
            json = JsonConvert.SerializeObject(new
            {
                id = 0,
                success = false,
                message = "Post was not created"
            });
        }

        return Content(json, "application/json");
    }


    [HttpPost, ValidateInput(false)]
    public ContentResult EditPost(Post post)
    {
        string json;

        ModelState.Clear();

        if (TryValidateModel(post))
        {
            _serviceRepository.EditPost(post, Tags);

            json = JsonConvert.SerializeObject(new
                                                {
                                                    id = post.Id,
                                                    success = true,
                                                    message = "Post updated successfully"
                                                });
        }
        else
        {
            json = JsonConvert.SerializeObject(new
            {
                id = 0,
                success = false,
                message = "Failed to save the changes."
            });

        }

        return Content(json, "application/json");
    }
 }

我也在使用Post的自定义模型绑定器,如下所示

public class PostModelBinder : DefaultModelBinder
{
    private readonly IKernel _kernel;

        public PostModelBinder(IKernel kernel)
        {
            _kernel = kernel;
        }

    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            var post = (Post)base.BindModel(controllerContext, bindingContext);

            var _blogRepository = _kernel.Get<IServiceRepository>();

    }

    var tags = bindingContext.ValueProvider.GetValue("Tags").AttemptedValue.Split(',');

    if (tags.Length > 0)
        {
                post.Tags = new List<Tag>();

                foreach (var tag in tags)
                {
                    post.Tags.Add(_serviceRepository.Tag( int.Parse(tag.Trim()) ));
                }
        }

    return post;
}

0 个答案:

没有答案