Property方法只能与原始或复杂属性一起使用。使用Reference或Collection方法

时间:2017-04-09 19:42:39

标签: c# entity-framework linq

  

属性'标签'在类型' Post'不是原始或复杂的财产。 Property方法只能与原始或复杂属性一起使用。使用Reference或Collection方法。

我正在使用此代码段来更新帖子文本和相关标签:

            var tags = TagConverter.FetchTags(postText);
            var newTags = tags.Select(t => t.Title);
            var savedTags = _db.Tags.Where(t => newTags.Contains(t.Title)).ToList();
            var notSavedTags = tags.Where(t => savedTags.All(st => st.Title != t.Title)).ToList();
            var insertedTags = _db.Tags.AddRange(notSavedTags).ToList();
            insertedTags.AddRange(savedTags);
            _db.SaveChanges();


            var updatedPost = post;
            updatedPost.Title = postText;
            updatedPost.Tags = insertedTags;
            _db.Posts.Attach(updatedPost);
            var entry = _db.Entry(updatedPost);
            entry.Property(e => e.Title).IsModified = true;
            entry.Property(e => e.Tags).IsModified = true;


            _db.SaveChanges();

如何更新标签?

2 个答案:

答案 0 :(得分:0)

设置IsModified适用于单个实体,而不适用于集合。这就是为什么这条线不起作用的原因:

entry.Property(e => e.Tags).IsModified = true;

由于您已将所有代码附加到上下文,因此您需要手动将updatedPost.Tags集合与insertedTags进行比较和更新。

答案 1 :(得分:0)

首先,我认为只需拨打一次_db.SaveChanges();就可以正常工作。

由于这一行你会得到一个例外,只需删除它:

entry.Property(e => e.Tags).IsModified = true;

另外,我会说 _db.Posts.Attach(updatedPost);updatedPost.Tags = insertedTags;之前。 完成这些更改后,您的代码最有可能正常运行。

另一种选择是使用ChangeRelationshipState()方法。请在下面的代码中查看它。您还可以查看此EF Relationships and Navigation Properties doc以获取更多信息(请参阅“创建和修改关系”部分)。

我只更改了代码的第二部分,还添加了“使用”:

using System.Data.Entity.Infrastructure;

var tags = TagConverter.FetchTags(postText);
var newTags = tags.Select(t => t.Title);
var savedTags = _db.Tags.Where(t => newTags.Contains(t.Title)).ToList();
var notSavedTags = tags.Where(t => savedTags.All(st => st.Title != t.Title)).ToList();
var insertedTags = _db.Tags.AddRange(notSavedTags).ToList();
insertedTags.AddRange(savedTags);
_db.SaveChanges();


var updatedPost = post();
_db.Posts.Attach(updatedPost);
updatedPost.Title = postText;

var entry = _db.Entry(updatedPost);
entry.Property(e => e.Title).IsModified = true;

foreach (var tag in insertedTags)
{
   ((IObjectContextAdapter)DbContext).ObjectContext.ObjectStateManager.
   ChangeRelationshipState(updatedPost, tag, e => e.Tags, EntityState.Added);
} 

_db.SaveChanges();