Property 方法只能与原始或复杂属性一起使用。使用参考或收藏方法

问题描述 投票:0回答:3

“Post”类型上的“Tags”属性不是原始属性或复杂属性。 Property 方法只能与原始或复杂属性一起使用。使用参考或收集方法。

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

            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();

如何更新标签?

c# entity-framework linq
3个回答
0
投票

设置

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

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

由于您已经将所有标签附加到上下文,因此您需要手动将

updatedPost.Tags
集合与
insertedTags
进行比较和更新。


0
投票

首先,我认为只需调用一次

_db.SaveChanges();
就可以正常工作。

由于这一行,您会收到异常,只需将其删除:

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

另外,我会放

_db.Posts.Attach(updatedPost);
之前
updatedPost.Tags = insertedTags;
。 经过这些更改后,您的代码很可能应该可以工作。

另一种选择是使用 ChangeRelationshipState() 方法。看看下面的代码。您还可以查看此 EF 关系和导航属性文档 以获取更多信息(请参阅“创建和修改关系”部分)。

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

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();

0
投票

您遇到的错误“‘Post’类型上的属性‘Tags’不是原始或复杂属性。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();
_db.SaveChanges();

// Load the post and its current tags
var updatedPost = _db.Posts.Include(p => p.Tags).Single(p => p.Id == post.Id);

// Update the post's title
updatedPost.Title = postText;

// Update the tags
updatedPost.Tags.Clear();
foreach (var tag in insertedTags.Concat(savedTags))
{
    updatedPost.Tags.Add(tag);
}

// Mark the title as modified
_db.Entry(updatedPost).Property(e => e.Title).IsModified = true;

// Save the changes
_db.SaveChanges();
© www.soinside.com 2019 - 2024. All rights reserved.