我正在构建反馈功能。反馈应该有多个类别,应该可以根据类别找到反馈,因此存在多对多的关系。
我为此设置了以下代码,它首先设计为代码。
退款项目:
public class FeedbackItem
{
public FeedbackItem()
{
}
[Key]
public long Id { get; set; }
public virtual ICollection<FeedbackCategory> Categorys { get; set; }
//public
public string Content { get; set; }
public bool Notify { get; set; }
public string SubscriptionUserName { get; set; }
public string SubscriptionUserEmail { get; set; }
public long SubscriptionId { get; set; }
}
反馈类别:
public class FeedbackCategory
{
[Key]
public int Id { get; set; }
public string Value { get; set; }
public virtual ICollection<FeedbackItem> Feedbacks { get; set; }
}
数据库上下文:
public class FeedbackContext : DbContext, IFeedbackContext
{
public FeedbackContext() : base("DefaultConnection")
{
//Database.SetInitializer<FeedbackContext>(new FeedbackContextDbInitializer());
}
public DbSet<FeedbackItem> FeedbackItems { get; set; }
public DbSet<FeedbackCategory> Categories { get; set; }
}
和初始化程序
class FeedbackContextDbInitializer : DropCreateDatabaseAlways<FeedbackContext>
{
protected override void Seed(FeedbackContext context)
{
IList<FeedbackCategory> categories = new List<FeedbackCategory>()
{
new FeedbackCategory() { Value = "Android" },
new FeedbackCategory() { Value = "API" }
};
foreach (var feedbackCategory in categories)
{
context.Categories.Add(feedbackCategory);
}
base.Seed(context);
}
}
上面的代码在运行时会生成三个表。这些是FeedbackCategories
,FeedbackCategoryFeedbackItems
和FeedbackItems
表FeedbackCategories附有一些已存在的类别。当我尝试创建一个包含一个或多个类别的新FeedbackItem时,就会出现问题。
我提供的Json如下:
{
"categorys": [
{
"$id": "1",
"Feedbacks": [],
"Id": 1,
"Value": "Android"
}
],
"subscriptionUserName": "name",
"subscriptionUserEmail": "my@email.com",
"content": "this is a feedback item",
"notify": false,
"subscriptionId": 2
}
将其转换为FeedbackItem
并由以下代码处理
public class FeedbackSqlRepository : IFeedbackSqlRepository
{
public int Create(FeedbackItem feedback)
{
if (feedback == null)
{
throw new ArgumentNullException("feedback", "FeedbackItem cannot be empty.");
}
using (var context = new FeedbackContext())
{
context.FeedbackItems.Add(feedback);
return context.SaveChanges();
}
}
}
这里发生的事情是EF创建一个新的FeedbackItem
,一个新的FeedbackCategory
将创建的反馈项映射到FeedbackCategoryFeedbackItems
表中新创建的反馈类别。
这不是我想要的工作
我想要以下内容:
创建新的FeedbackItem
并尊重FeedbackCategory
表中的现有FeedbackCategoryFeedbackItems
。我对EF的了解太少,无法理解这里出了什么问题,以及如何做好首选工作。
======
修复了FeedbackSqlRepository
:
foreach (FeedbackCategory feedbackCategory in feedback.Categories)
{
context.Entry(feedbackCategory).State = EntityState.Unchanged;
}
context.FeedbackItems.Add(feedback);
return context.SaveChanges();
答案 0 :(得分:3)
实体框架不会检查实体内容,并确定它们是新的还是已添加。
DbSet.Add()会将对象图中的所有实体标记为已添加,并在调用SaveChanges()时生成插入。
DbSet.Attach()将所有标记为未修改的实体留下。
如果你的某些实体是新的,有些是修改的,有些只是引用,那么你应该使用Add()或Attach(),然后在调用SaveChanges()之前手动设置实体状态。
DbContext.Entry(entity).State = EntityState.Unmodified