我有以下代码
var newPost = new Post()
{
Activity = new Activity { Type = 1, ActivityTotalStatistic = new ActivityTotalStatistic() },
CreatedDate = oldPost.DateTimeCreated,
CategoryId = categoryId,
Title = oldPost.Name,
OwnerId = oldPost.UserID,
Slug = oldPost.Name,
LastUpdateDate = oldPost.DateTimeCreated,
PublishDate = oldPost.DateTimeCreated,
PostStatistic = new PostStatistic(),
PostItems = new List<PostItem>
{
new PostItem
{
Activity = new Activity { Type = 2},<-- note this line of code
CreatedDate = oldPost.DateTimeCreated,
Title = oldPost.Name,
Type = 1,
Content = oldPost.Path
}
}
};
newDb.Posts.Add(newPost);
newDb.SaveChanges();
这是事件和统计表的 SQL 架构
create table ActivityTotalStatistics
(
Id int primary key identity(1,1),
NumberOfLikes int not null,
NumberOfDislikes int not null,
SumOfLikes int not null,
CommentCount int not null
)
create table Activities
(
Id int identity (1,1) primary key,
Type int not null,
ActivityTotalStatisticId int not null
foreign key references ActivityTotalStatistics(Id)
)
正如您所看到的,每个事件都应该有事件统计信息,因为外键不可为空,并且我的代码应该中断,因为帖子项中的事件没有实例化事件统计信息。
但是 EF 不识别它。发生的情况是帖子项目从这行代码接收到相同的事件统计信息
Activity = new Activity { Type = 1, ActivityTotalStatistic = new ActivityTotalStatistic() },
这是 Entity Framework 的有效行为吗?
更新 Activity.cs模型
public partial class Activity
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Activity()
{
this.ActivityLikes = new HashSet<ActivityLike>();
this.Comments = new HashSet<Comment>();
this.PostItems = new HashSet<PostItem>();
this.Posts = new HashSet<Post>();
}
public int Id { get; set; }
public int Type { get; set; }
public int ActivityTotalStatisticId { get; set; }
public virtual ActivityTotalStatistic ActivityTotalStatistic { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<ActivityLike> ActivityLikes { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Comment> Comments { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<PostItem> PostItems { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Post> Posts { get; set; }
}
ActivityTotalStatistic.cs
public partial class ActivityTotalStatistic
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public ActivityTotalStatistic()
{
this.Activities = new HashSet<Activity>();
}
public int Id { get; set; }
public int NumberOfLikes { get; set; }
public int NumberOfDislikes { get; set; }
public int SumOfLikes { get; set; }
public int CommentCount { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Activity> Activities { get; set; }
}
最佳答案
Is this a valid behavior of Entity Framework?
我不这么认为 - 不幸的是,这些跟踪行为没有官方文档/规范,但看起来像是实现特定的副作用/缺陷(错误)。
理由:
仅当更改跟踪器包含具有自动生成的 PK 的单个已添加
主体实体时,才会发生这种情况,依赖实体具有显式引用导航属性和FK 属性,全部具有默认值(“0”和 null
)。
如果满足以下条件,则不会发生:
(1) 还有第二个已添加
主体实体:
newDb.Set<ActivityTotalStatistic>().Add(new ActivityTotalStatistic());
SaveChanges
抛出 DbUpdateException
:
Unable to determine the principal end of the 'Activity_ActivityTotalStatistic' relationship. Multiple added entities may have the same primary key.
不是很用户友好,但仍然是异常(exception)。
(2) 依赖实体没有显式 FK 属性,但正确配置了所需的影子 FK 属性。 SaveChanges
抛出:
Entities in 'MyDbContext.Activities' participate in the 'Activity_ActivityTotalStatistic' relationship. 0 related 'Activity_ActivityTotalStatistic_Target' were found. 1 'Activity_ActivityTotalStatistic_Target' is expected.
同样不是很用户友好,但仍然是异常(exception)。
(3) 引用导航属性应用了 [Required]
属性:
[Required]
public virtual ActivityTotalStatistic ActivityTotalStatistic { get; set; }
SaveChanges
抛出包含 ValidationError
的 ValidationException
以及(最终)用户友好的消息:
The ActivityTotalStatistic field is required.
回到最初的案例。仅且仅在该特定情况下,EF 会找到单个待处理的 Added
主体实体实例,并将其与所有具有 ActivityTotalStatistic == null
和 ActivityTotalStatisticId = 的待处理依赖实体关联起来。 = 0
。
对我来说,所有这些都表明存在错误/意外的 EF6 行为。防止这种情况的最佳方法似乎是使用 [Required
] 属性装饰所需的引用导航属性,但这在像您这样的 Database First (edmx) 生成的实体模型中是有问题的。
关于c# - Entity Framework 6,验证未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54745047/