2013-02-08 40 views
1

由於我在處理ASP.NET MVC項目,所以我看到了一個奇怪的EF行爲,這會延遲我(確切地說,我仍然在這個問題上停留在最少一個月...只有現在我已經意識到我的DDD架構代碼沒有被破壞,並且它是特定的EF相關的代碼錯誤)。實體框架自動將新的實例實體分配爲已刪除

我的網站有帖子。每個帖子都有一個屬性集(PostAttributeValue),並且每個屬性值都有一個相關的PostAttributeDefinition其中包含有關它的數據 - 如標題,驗證規則,原始值(二進制序列化),數據類型等

這是我的帖子型號:

public class Post 
{ 
    #region Settings 

    /// <summary> 
    /// Maximum linked images 
    /// </summary> 
    public static int MaximumLinkedImages 
    { 
     get { return Properties.Settings.Default.MaximumPostsLinkedImages; } 
    } 

    /// <summary> 
    /// Maximum linked image size in MB 
    /// </summary> 
    public static int MaximumLinkedImageSize 
    { 
     get { return Properties.Settings.Default.MaximumPostLinkedImageSize; } 
    } 

    /// <summary> 
    /// Delay hours between posts bumping 
    /// </summary> 
    public static int BumpPostDelayHours 
    { 
     get { return Properties.Settings.Default.BumpPostDelayHours; } 
    } 

    #endregion 

    #region ctor 

    public Post() 
    { 
     this.Attributes = new List<PostAttributeValue>(); 
     this.LinkedImages = new List<string>(); 
    } 

    #endregion 

    /// <summary> 
    /// The parent category that this post was posted into 
    /// </summary> 
    [Required] 
    public virtual Category ParentCategory { get; set; } 

    /// <summary> 
    /// The post unique identifier 
    /// </summary> 
    [Key] 
    public Guid PostIdentifier { get; set; } 

    /// <summary> 
    /// The post title (e.g. "Great vila!") 
    /// </summary> 
    [Required] 
    public string Title { get; set; } 

    /// <summary> 
    /// The post title url alias (e.g. "great-vila") 
    /// </summary> 
    public string TitleUrlAlias { get; set; } 

    /// <summary> 
    /// Post extra notes and information written by the author 
    /// </summary> 
    [Required] 
    public string Description { get; set; } 

    /// <summary> 
    /// The post item city 
    /// </summary> 
    [Required] 
    public virtual City City { get; set; } 

    /// <summary> 
    /// The post item location 
    /// </summary> 
    public string Location { get; set; } 

    /// <summary> 
    /// Is the post was published and marketed by brokerage (Tivuuch) 
    /// </summary> 
    [Required] 
    public bool Brokerage { get; set; } 

    /// <summary> 
    /// Post custom attributes 
    /// </summary> 
    public virtual ICollection<PostAttributeValue> Attributes { get; set; } 

    /// <summary> 
    /// The post assigned price 
    /// </summary> 
    [Required] 
    public int RequestedPrice { get; set; } 

    /// <summary> 
    /// List of images linked with the post (includes only the name of the picture, a.k.a "foo.png", "bar.jpg" etc.) 
    /// </summary> 
    public virtual ICollection<string> LinkedImages { get; set; } 

    public string LinkedImagesSerialized 
    { 
     get 
     { 
      if (this.LinkedImages == null) 
      { 
       this.LinkedImages = new List<string>(); 
      } 

      return string.Join(",", this.LinkedImages); 
     } 
     set 
     { 
      if (this.LinkedImages == null) 
      { 
       this.LinkedImages = new List<string>(); 
      } 

      if (string.IsNullOrEmpty(value)) 
      { 
       return; 
      } 

      this.LinkedImages = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList(); 
     } 
    } 

    /// <summary> 
    /// Cached generated cached url using IShorterUrlService 
    /// </summary> 
    public string GeneratedShorterUrl { get; set; } 

    /// <summary> 
    /// Is this post marked as hot 
    /// </summary> 
    public bool IsHotPost { get; set; } 

    /// <summary> 
    /// The post publish status 
    /// </summary> 
    public PostPublishStatus PublishStatus { get; set; } 

    /// <summary> 
    /// The post author 
    /// </summary> 
    public virtual Account Author { get; set; } 

    /// <summary> 
    /// The author IP address (collected to determine different IPs) 
    /// </summary> 
    public string AuthorIPAddress { get; set; } 

    /// <summary> 
    /// The creation date of the post 
    /// </summary> 
    public DateTime CreationDate { get; set; } 

    /// <summary> 
    /// The last post modification date 
    /// </summary> 
    public DateTime LastUpdatedDate { get; set; } 

    /// <summary> 
    /// The date that the post was bumped at, used to sort the posts in category. 
    /// </summary> 
    public DateTime LastBumpDate { get; set; } 
} 

這是PostAttributeValue 公共類PostAttributeValue {/// /// 屬性的值id /// [關鍵] 公衆詮釋AttributeValueId {獲得;組; }

/// <summary> 
    /// The value owner post 
    /// </summary> 
    public virtual Post OwnerPost { get; set; } 

    /// <summary> 
    /// The value attribute definition id 
    /// </summary> 
    //public int RelatedAttributeDefinitionId { get; set; } 

    /// <summary> 
    /// The value attribute definition 
    /// </summary> 
    public virtual PostAttributeDefinition Definition { get; set; } 

    /// <summary> 
    /// The stored raw value 
    /// </summary> 
    public byte[] RawValue { get; set; } 
} 

,這是PostAttributeDefinition 公共類PostAttributeDefinition {/// /// 的過濾器名稱 /// [關鍵] 公衆詮釋DefinitionId {獲得;組; }

/// <summary> 
    /// The owner category 
    /// </summary> 
    [Required] 
    public virtual Category OwnerCategory { get; set; } 

    /// <summary> 
    /// The filter title 
    /// </summary> 
    [Required] 
    public string Title { get; set; } 

    /// <summary> 
    /// Metadata enum that provides extra data about the data type 
    /// </summary> 
    public PostAttributeTypeMetadata TypeMetadata { get; set; } 

    /// <summary> 
    /// Bitwise metadata that provides data about the object in display mode 
    /// </summary> 
    public PostAttributeDisplayModeMetadata DisplayModeMetadata { get; set; } 

    public PostAttributeEditorType EditorType { get; set; } 

    /// <summary> 
    /// The attribute raw default value 
    /// </summary> 
    [Required] 
    public byte[] RawDataValue { get; set; } 

    /// <summary> 
    /// The attribute raw associated validation attributes 
    /// </summary> 
    public byte[] RawValidationRules { get; set; } 

    /// <summary> 
    /// Is this field required 
    /// </summary> 
    public bool IsRequired { get; set; } 
} 

我的問題是,當我試圖添加一個新的文章中,我得到一個錯誤的關係(A relationship from the AssociationSet is in the 'Deleted' state) 這是

A relationship from the 'PostAttributeValue_Definition' AssociationSet is in the 'Deleted' state. Given multiplicity constraints, a corresponding 'PostAttributeValue_Definition_Source' must also in the 'Deleted' state. 

現在,我已經看到,問題在於,當我爲PostAttributeValue分配一個定義時,它會自動變爲Deleted - 即使我正在分配一個我現在從DB中獲取的定義。

我測試上面的代碼:

 var db = ServiceLocator.SharedInstance.GetInstance<MyDbContext>(); 
     List<PostAttributeValue> v = new List<PostAttributeValue>(); 

     var entity = db.PostAttributesDefinitions.Where(d => d.DefinitionId==1).Include(d => d.OwnerCategory).First(); 
     v.Add(new PostAttributeValue() { Definition = entity }); 

     Post post = new Post() 
     { 
      Title = "foo", 
      Description = "bar", 
      City = new City { }, 
      Brokerage = false, 
      Location = "", 
      RequestedPrice = 500, 
      ParentCategory = new Category() { }, 
      AuthorIPAddress = "", 
      Attributes = v 
     }; 

     db.Posts.Add(post); 

     var deletedValuesStore = ((System.Data.Entity.Infrastructure.IObjectContextAdapter)db) 

.ObjectContext.ObjectStateManager.GetObjectStateEntries(System.Data.EntityState.Deleted);

並看到deletedValuesStore包含1項 - 定義。當我評論此行時,商店中沒有物品。

你有什麼想法如何解決? 感謝您的時間!

回答

1

好吧,我想通了。 爲了防止有人感興趣,我將DbContext配置爲Required()。WithOptional()關係,而不是一對多 - Required()。WithMany()。 因此,當我將已經分配給某個值的現有屬性定義分配給一個新值時,它會自動將其標記爲已刪除。