2010-08-27 32 views
6

Tình huống: Tôi có đối tượng khách hàng đã tải chậm. Tôi sử dụng nó trong suốt chương trình để gọi một danh sách khách hàng cho một hộp danh sách. Nó có mối quan hệ với các đối tượng Division_Customer_Rel, Division_Email_Rel và Email_Address. Tất cả các mối quan hệ đều có Lazy = true, Cascade = ManyRelationCascadeEnum.AllDeleteOrphan, Inverse = true.Một đối tượng khác có cùng số nhận dạng đã được liên kết với lỗi phiên

Sự cố: Khi tôi đang sử dụng phiên mới và tôi thử lưu nó sẽ cho tôi lỗi A different object with same identifier was already associated with the session. Tôi đã cố gắng sử dụng LINQ để trả về danh sách mà không cần sử dụng một phiên mới bằng cách tham gia các đối tượng khác trong cuộc gọi nhưng tôi không chắc chắn cách sử dụng ActiveRecordLinq <> khi tham gia.

private Customer GetCustomer() 
    { 
     return (from x in ActiveRecordLinq.AsQueryable<Customer>() 
     where x.Customer_ID == ((Customer)lst_customers.SelectedItem).Customer_ID 
     select x).First(); 
    } 

Mã sản sinh ra lỗi

using (new SessionScope()) 
       { 
       //var sess = GetSession(); 
       //var customer = 
       // sess.CreateCriteria<Customer>("c").CreateCriteria("c.DivisionCustomer_Rels").List<Customer>(). 
       //  First(); 
       var customer = GetCustomer(); 
        /* Ensure user wishes to commit the data. */ 

        var result = 
         MessageBox.Show(
          @"You are about to submit changes to customer: " + customer.CustomerName + @"." + 
          Environment.NewLine + Environment.NewLine + 
          @"Submit Changes?", @"Submit Customer Changes", MessageBoxButtons.YesNo, 
          MessageBoxIcon.Question); 
        if (result == DialogResult.Yes) 
        { 
         customer.CustomerName = txt_custName.Text; 
         customer.NamcisNumber = Convert.ToInt32(txt_namcis.Text); 
         customer.DCA = chk_dca.Checked; 
         customer.CustomerType = (CustomerType_Code) cmb_custType.SelectedItem; 
         customer.AOR = (AOR_Code) cmbAOR.SelectedItem; 
         customer.CSRep = (CSRep_Code) cmbCSRep.SelectedItem; 
         customer.DivisionCustomer_Rels.Clear(); 
         foreach (var t in lst_SectorCust.Items) 
         { 
          customer.DivisionCustomer_Rels.Add(new Division_Customer_Rel 
                    { 
                     Customer = customer 
                     , 
                     Division = (Division_Code) t, 
                     MarkedForDeletion = false 
                    }); 
         } 
         customer.CircuitCustomer_Rels.Clear(); 
         foreach (var t in lst_Circuit.Items) 
         { 
          customer.CircuitCustomer_Rels.Add(new Circuit_Customer_Rel 
                    { 
                     Circuit = (Circuit) t, 
                     Customer = customer, 
                     MarkedForDeletion = false 
                    }); 
         } 
         customer.EmailAddresses.Clear(); 
         foreach (var t in lst_email.Items) 
         { 
          var temp = (Email_Address)t; 
          temp.Customer = customer; 
          customer.EmailAddresses.Add(temp); 

         } 
         ////Need to manage the emails this way otherwise we recieve an error because of lazy loading 
         //foreach (var temp in lst_email.Items.Cast<Email_Address>()) 
         //{ 
         // temp.Customer = customer; 
         // if (!customer.EmailAddresses.Any(s=>temp.ToString().Equals(s.ToString())) && !customer.EmailAddresses.Contains(temp)) 
         // { 
         //  customer.EmailAddresses.Add(temp); 
         // } 

         //} 

         //var text = IList<Email_Address> lst_email.Items; 
         //var tem = customer.EmailAddresses.Except(lst_email.Items); 
         //for (var i = customer.EmailAddresses.Count - 1; i >= 0;i--) 
         //{ 
         // var temp = customer.EmailAddresses[i]; 

         // for (var j = 0; j < lst_email.Items.Count; j++) 
         // { 
         //  if (temp.ToString()!=lst_email.Items[j].ToString()) 
         //  { 
         //   customer.EmailAddresses.Remove(temp); 
         //  } 
         // } 
         //} 
         customer.DivisionEmail_Rels.Clear(); 
         customer.Save(); 
         MessageBox.Show(@"Changes submitted."); 
        } 
        //SessionScope.Current 
       } 

Địa chỉ Email Lớp

namespace Sens 
{ 
    using System; 
    using System.Collections.Generic; 
    using Castle.ActiveRecord; 

    [Serializable, ActiveRecord("dbo.Email_Address")] 
    public class Email_Address : ActiveRecordValidationBase<Email_Address> 
    { 
     #region Constructors 

     public Email_Address() 
     { 
      DivisionEmail_Rels = new List<Division_Email_Rel>(); 
     } 

     #endregion 

     #region Properties 

     [PrimaryKey(Column = "Email_ID")] 
// ReSharper disable InconsistentNaming 
     public int Email_ID { get; private set; } 

     [BelongsTo(Column = "Customer_ID")] 
     public Customer Customer { get; set; } 

     [Property(Column = "[Email]", NotNull = true, Length = 100)] 
     public string Email { get; set; } 

     [BelongsTo(Column = "EmailType_ID")] 
     public EmailType_Code EmailType { get; set; } 

     [Property(Column = "[ReceivesSENS]", NotNull = true)] 
     public bool ReceivesSENS { get; set; } 

     [Property(Column = "[MarkedForDeletion]", NotNull = true)] 
     public bool MarkedForDeletion { get; set; } 

     #endregion 

     #region HasMany DivisionEmail_Rels 

     [HasMany(typeof(Division_Email_Rel), Lazy = false,Cascade=ManyRelationCascadeEnum.AllDeleteOrphan,Inverse=true)] 
     public IList<Division_Email_Rel> DivisionEmail_Rels { get; set; } 

     #endregion 
    } 
} 

phận khách hàng Rel

namespace Sens 
{ 
    using System; 
    using Castle.ActiveRecord; 

    [Serializable, ActiveRecord("dbo.Division_Customer_Rel")] 
    public class Division_Customer_Rel : ActiveRecordValidationBase<Division_Customer_Rel> 
    { 
     #region Constructors 

     #endregion 

     #region Properties 

     [PrimaryKey(Column = "Relationship_ID")] 
// ReSharper disable InconsistentNaming 
     public int Relationship_ID { get; private set; } 
// ReSharper restore InconsistentNaming 

     [BelongsTo(Column = "Customer_ID")] 
     public Customer Customer { get; set; } 

     [BelongsTo(Column = "Division_ID")] 
     public Division_Code Division { get; set; } 

     [Property(Column = "[MarkedForDeletion]", NotNull = true)] 
     public bool MarkedForDeletion { get; set; } 

     #endregion 
    } 
} 

Division Email Rel

#region namespace imports 

using System; 
using Castle.ActiveRecord; 

#endregion 

namespace Sens 
{ 
    [Serializable, ActiveRecord("dbo.Division_Email_Rel")] 
    public class Division_Email_Rel : ActiveRecordValidationBase<Division_Email_Rel> 
    { 
     #region Constructors 

     #endregion 

     #region Properties 

     [PrimaryKey(Column = "Relationship_ID")] 
// ReSharper disable InconsistentNaming 
      public int Relationship_ID { get; private set; } 

// ReSharper restore InconsistentNaming 

     [BelongsTo(Column = "Email_ID", Cascade = CascadeEnum.All)] 
     public Email_Address Email { get; set; } 

     [BelongsTo(Column = "Division_ID")] 
     public Division_Code Division { get; set; } 

     [BelongsTo(Column = "Customer_ID")] 
     public Customer Customer { get; set; } 

     [Property(Column = "[MarkedForDeletion]", NotNull = true)] 
     public bool MarkedForDeletion { get; set; } 

     #endregion 
    } 
} 
+0

1. LINQ to SQL phải làm gì ở đây? Đó là một thư viện hoàn toàn khác. 2. Bạn có thể đăng các mã mà ném "Một đối tượng khác nhau với cùng một định danh đã được kết hợp với phiên"? –

+0

bạn cũng có thể đăng mã cho các lớp Division_Customer_Rel, Division_Email_Rel và Email_Address không? –

+0

@Mauricio Scheffer Tôi sẽ đăng mã vào thứ Hai (Công việc liên quan) – Gage

Trả lời

3

Cách cuối cùng tôi đã tiết kiệm được sau khi googling ở khắp mọi nơi cho một câu trả lời là để xóa Email_Addresses thay vì xóa chúng.

SessionScope.Current.Evict(customer.EmailAddresses); 
         foreach (var t in lst_email.Items) 
         { 
          var temp = (Email_Address)t; 
          temp.Customer = customer; 
          customer.EmailAddresses.Add(temp); 

         } 

Không chắc chắn lý do tại sao điều này làm việc, nếu ai đó có thể giải thích điều đó thật tuyệt. Tôi đăng bài này trên đây để hy vọng nó sẽ tiết kiệm thời gian cho người tiếp theo gặp phải lỗi này.

1

Lệnh xóa sẽ loại bỏ tham chiếu "Email_Address" cụ thể khỏi bộ nhớ cache cấp đầu tiên NHibernate.

Từ customer.EmailAddresses bạn đã xóa tất cả địa chỉ email trong bộ nhớ cache cấp đầu tiên NHibernate.

Sau đó, bạn sẽ nhận được các mục từ danh sách email trong lst_email và thêm chúng vào EmailAddress cho khách hàng dưới dạng đối tượng mới.

Các vấn đề liên quan