当我在一个实体上使用GetById()然后将子实体的集合设置为来自MVC视图的新列表时,我收到此错误.
操作失败:无法更改关系,因为一个或多个外键属性不可为空.当对关系进行更改时,相关的外键属性将设置为空值.如果外键不支持空值,则必须定义新关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象.
我不太明白这一行:
由于一个或多个外键属性不可为空,因此无法更改关系.
为什么要更改2个实体之间的关系?它应该在整个应用程序的整个生命周期内保持不变.
发生异常的代码很简单,即将集合中已修改的子类分配给现有父类.这有望满足删除子类,添加新类和修改的需要.我原以为Entity Framework会处理这个问题.
代码行可以提炼为:
var thisParent = _repo.GetById(1);
thisParent.ChildItems = modifiedParent.ChildItems();
_repo.Save();
Run Code Online (Sandbox Code Playgroud) 这两个实体是一对多的关系(由代码第一流畅的api构建).
public class Parent
{
public Parent()
{
this.Children = new List<Child>();
}
public int Id { get; set; }
public virtual ICollection<Child> Children { get; set; }
}
public class Child
{
public int Id { get; set; }
public int ParentId { get; set; }
public string Data { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
在我的WebApi控制器中,我有动作创建父实体(工作正常)并更新父实体(有一些问题).更新操作如下所示:
public void Update(UpdateParentModel model)
{
//what should be done here?
}
Run Code Online (Sandbox Code Playgroud)
目前我有两个想法:
获取一个名为existingby 的跟踪父实体model.Id,并将值model逐个赋值给实体.这听起来很愚蠢.在model.Children我不知道哪个孩子是新的,哪个孩子被修改(甚至删除).
通过创建一个新的父实体model …
这令人沮丧.这是一对相关对象,由数据库优先实体框架生成:
public partial class DevelopmentType
{
public DevelopmentType()
{
this.DefaultCharges = new HashSet<DefaultCharge>();
}
public System.Guid RowId { get; set; }
public string Type { get; set; }
public virtual ICollection<DefaultCharge> DefaultCharges { get; set; }
}
public partial class DefaultCharge
{
public System.Guid RowId { get; set; }
public decimal ChargeableRate { get; set; }
public Nullable<System.Guid> DevelopmentType_RowId { get; set; }
public virtual DevelopmentType DevelopmentType { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
这是我要调用以保存DevelopmentType的代码 - 它涉及到automapper,因为我们将实体对象与DTO区分开来:
public void SaveDevelopmentType(DevelopmentType_dto dt)
{ …Run Code Online (Sandbox Code Playgroud) 我正在使用存储库模式来提供对聚合的访问和保存.
问题是更新由实体关系组成的聚合.
例如,采取Order和OrderItem关系.聚合根Order管理自己的OrderItem集合.OrderRepository因此,一个人将负责更新整个聚合(没有OrderItemRepository).
使用Entity Framework 6处理数据持久性.
更新存储库方法(DbContext.SaveChanges()在别处发生):
public void Update(TDataEntity item)
{
var entry = context.Entry<TDataEntity>(item);
if (entry.State == EntityState.Detached)
{
var set = context.Set<TDataEntity>();
TDataEntity attachedEntity = set.Local.SingleOrDefault(e => e.Id.Equals(item.Id));
if (attachedEntity != null)
{
// If the identity is already attached, rather set the state values
var attachedEntry = context.Entry(attachedEntity);
attachedEntry.CurrentValues.SetValues(item);
}
else
{
entry.State = EntityState.Modified;
}
}
}
Run Code Online (Sandbox Code Playgroud)
在上面的示例中,仅Order更新实体,而不更新其关联的OrderItem …
domain-driven-design entity-framework repository-pattern onion-architecture entity-framework-6
我知道它之前已被问过,但经过长时间的搜索和编码后,我无法采用干净利落的方法.这是我有的:
public class QuestionModel
{
public int QuestionID { get; set; }
public string QuestionText { get; set; }
public IList<QuestionChoiceModel> Choices { get; set; }
}
public class QuestionChoiceModel
{
public int ChoiceID { get; set; }
public string ChoiceText { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我在这个ASP.Net MVC应用程序中使用EF 5.Ninject使用的通用存储库模式和依赖注入InRequestScope()已经到位并且工作顺利.这些模型映射到实体/从实体映射没有问题.
向数据库添加新问题很简单.我设置了一些QuestionChoice实例的Question属性,EF处理其余的.
问题是关于更新.假设我们在3个QuestionChoices的数据库中有一个问题:
ChoiceID QuestionID ChoiceText
-------- ---------- ----------
1 1 blah blah
2 1 blah blah
3 1 blah blah
Run Code Online (Sandbox Code Playgroud)
当打开问题的编辑页面(GET:/ Questions/Edit/1)时,我使用foreachRazor 显示这3个选项.我已经写了一些JQuery代码,如果用户愿意,可以为输入元素添加或删除所需的标记.所以,用ID = 1的QuestionChoice可能在客户端进行编辑,ID = 2可能会被删除,并且新的ID …