代码之家  ›  专栏  ›  技术社区  ›  Gage

具有相同标识符的不同对象已与会话错误关联

  •  6
  • Gage  · 技术社区  · 16 年前

    我有一个启用了延迟加载的客户对象。我在整个程序中使用它来调用一个列表框的客户列表。它与部门\客户\关系、部门\电子邮件\关系和电子邮件\地址对象有关系。所有的关系都有 Lazy = true, Cascade = ManyRelationCascadeEnum.AllDeleteOrphan, Inverse = true

    当我使用一个新的会话,我试图保存它给我的错误 A different object with same identifier was already associated with the session

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

    产生错误的代码

    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
                    }
    

       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
        }
    }
    

    部门客户关系

        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
        }
    }
    

     #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
        }
    }
    
    2 回复  |  直到 16 年前
        1
  •  3
  •   Gage    16 年前

    在到处搜索答案之后,我最终得到了保存的方法是清除电子邮件地址,而不是清除它们。

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

    不知道为什么这样做,但如果有人能解释这将是伟大的。我把这个贴在这里,希望它能为下一个遇到这个错误的人节省一些时间。

        2
  •  1
  •   mashtheweb    13 年前

    逐出从NHibernate一级缓存中删除特定的“Email\u Address”引用。

    从客户电子邮件地址您已删除NHibernate一级缓存中的所有电子邮件地址。

    然后,您将从lst\u email中的电子邮件列表中获取项目,并将它们作为新对象添加到客户的EmailAddress中。

    推荐文章