首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >实体框架6 AttachAsModified

实体框架6 AttachAsModified
EN

Stack Overflow用户
提问于 2015-06-29 09:49:51
回答 2查看 329关注 0票数 0

我试图更新EF从4.x到6.x (最新稳定通过nuget)。经过一些工作后,该应用程序用于数据检索,但不用于保存。

出于性能原因,我们主要使用EF 4.x中的"AttachAsModified“方法。在大多数情况下,我们有主键,附加,修改我们想要更新的值,最后保存。

EF 6.x没有这样的方法,所以我尝试了以下方法:

代码语言:javascript
复制
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的调用)

代码语言:javascript
复制
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));
    }
}

我得到的错误消息如下:

  • “一个或多个实体的验证失败。有关详细信息,请参阅'EntityValidationErrors‘属性。”
  • “字段\”CreatedBy“是必需的。”

第一个问题:我在哪里可以看到或设置哪些字段是需要的?我们目前使用的是数据库优先方法。

第二个问题:有解决办法吗?生成的update查询不更新这些附加属性。当然,我可以将这些附加属性设置为一些随机值,并将这些属性标记为不变,但我希望有更好的方法。

谢谢你的帮忙!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-06-29 10:02:50

( 1)在哪里可以看到或设置需要哪些字段?

它们在edmx文件中标记为不可空:

或者用必需的属性标记它们:

代码语言:javascript
复制
[Required]
public string Name { get; set;} 

或者用Fluent API标记IsRequired()调用:

代码语言:javascript
复制
modelBuilder.Entity<Person>().Property(t => t.Name).IsRequired();

或者,它们现在允许设置空值:

代码语言:javascript
复制
public int Age { get; set; }

例如,这允许空值:

代码语言:javascript
复制
public int? Age { get; set; }

( 2)有解决办法吗?

对于部分更新,我知道唯一的解决办法是在未修改的属性上设置一些垃圾值,仅仅是为了通过验证。例如,让我们用id =1更新person的age属性:

代码语言:javascript
复制
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();

重要:不需要附加()。

票数 1
EN

Stack Overflow用户

发布于 2015-07-01 10:57:25

我发现验证只是不适用于部分更新。一种解决方案是重写ValidateEntity方法或通过将ValidateOnSaveEnabled proeprty设置为false来禁用验证。两者都位于db配置类中。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31112578

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档