我试图更新EF从4.x到6.x (最新稳定通过nuget)。经过一些工作后,该应用程序用于数据检索,但不用于保存。
出于性能原因,我们主要使用EF 4.x中的"AttachAsModified“方法。在大多数情况下,我们有主键,附加,修改我们想要更新的值,最后保存。
EF 6.x没有这样的方法,所以我尝试了以下方法:
var data = new CatalogNode
{
CatalogNodeId = catalogNodeId,
UpdatedOn = updatedOn,
UpdatedBy = updatedBy,
};
CatalogNodes.Attach(data);
var entry = Entry(data);
entry.Property(e => e.UpdatedOn).IsModified = true;
entry.Property(e => e.UpdatedBy).IsModified = true;不幸的是,EF抛出一个"DbEntityValidationException“,表示需要设置一些额外的属性。
编辑:
下面是生成的CatalogNodes实体(setter包括对OnPropertyChanged的调用)
public partial class CatalogNode : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public CatalogNode()
{
this.CatalogArticles = new HashSet<CatalogArticle>();
this.LocalizedCatalogNodes = new HashSet<LocalizedCatalogNode>();
this.CatalogNodeAttributeValues = new HashSet<CatalogNodeAttributeValue>();
this.CatalogNodeMappings = new HashSet<CatalogNodeMapping>();
this.TranslatedCatalogNodeNames = new HashSet<TranslatedCatalogNodeName>();
this.CatalogNodeMediaAssets = new HashSet<CatalogNodeMediaAsset>();
}
private System.Guid _catalognodeid;
public System.Guid CatalogNodeId {get;set;}
private string _catalognodeuid;
public string CatalogNodeUid {get;set;}
private System.Guid _catalogid;
public System.Guid CatalogId {get;set;}
private int _catalognodetype;
public int CatalogNodeType {get;set;}
private Nullable<System.Guid> _parentid;
public Nullable<System.Guid> ParentId {get;set;}
private Nullable<System.Guid> _linkid;
public Nullable<System.Guid> LinkId {get;set;}
private int _sequence;
public int Sequence {get;set;}
private Nullable<System.Guid> _attributegroupid;
public Nullable<System.Guid> AttributeGroupId {get;set;}
private string _printcatalogtemplateuid;
public string PrintCatalogTemplateUid {get;set;}
private bool _printcatalogpagebreak;
public bool PrintCatalogPageBreak {get;set;}
private System.DateTime _createdon;
public System.DateTime CreatedOn {get;set;}
private string _createdby;
public string CreatedBy {get;set;}
private System.DateTime _updatedon;
public System.DateTime UpdatedOn {get;set;}
private string _updatedby;
public string UpdatedBy {get;set;}
public virtual AttributeGroup AttributeGroup { get; set; }
public virtual Catalog Catalog { get; set; }
public virtual ICollection<CatalogArticle> CatalogArticles { get; set; }
public virtual ICollection<LocalizedCatalogNode> LocalizedCatalogNodes { get; set; }
public virtual ICollection<CatalogNodeAttributeValue> CatalogNodeAttributeValues { get; set; }
public virtual CatalogNode LinkedCatalogNode { get; set; }
public virtual ICollection<CatalogNodeMapping> CatalogNodeMappings { get; set; }
public virtual ICollection<TranslatedCatalogNodeName> TranslatedCatalogNodeNames { get; set; }
public virtual ICollection<CatalogNodeMediaAsset> CatalogNodeMediaAssets { get; set; }
public void OnPropertyChanged(string propertyName)
{
if(PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}我得到的错误消息如下:
第一个问题:我在哪里可以看到或设置哪些字段是需要的?我们目前使用的是数据库优先方法。
第二个问题:有解决办法吗?生成的update查询不更新这些附加属性。当然,我可以将这些附加属性设置为一些随机值,并将这些属性标记为不变,但我希望有更好的方法。
谢谢你的帮忙!
发布于 2015-06-29 10:02:50
( 1)在哪里可以看到或设置需要哪些字段?
它们在edmx文件中标记为不可空:

或者用必需的属性标记它们:
[Required]
public string Name { get; set;} 或者用Fluent API标记IsRequired()调用:
modelBuilder.Entity<Person>().Property(t => t.Name).IsRequired();或者,它们现在允许设置空值:
public int Age { get; set; }例如,这允许空值:
public int? Age { get; set; }( 2)有解决办法吗?
对于部分更新,我知道唯一的解决办法是在未修改的属性上设置一些垃圾值,仅仅是为了通过验证。例如,让我们用id =1更新person的age属性:
var person = new Person();
person.Id = 1;
person.Name = ""; // not null string to pass validation
person.Age = 25;
var entry = context.Entry(person);
entry.Property(e => e.Age).IsModified = true;
context.SaveChanges();重要:不需要附加()。
发布于 2015-07-01 10:57:25
我发现验证只是不适用于部分更新。一种解决方案是重写ValidateEntity方法或通过将ValidateOnSaveEnabled proeprty设置为false来禁用验证。两者都位于db配置类中。
https://stackoverflow.com/questions/31112578
复制相似问题