Scenario: I have a customer object with lazy loading enabled. I use that throughout the program to call a list of customer for a listbox. It has relationships to the Division_Customer_Rel, Division_Email_Rel and Email_Address objects. All off the relationships have Lazy = true, Cascade = ManyRelationCascadeEnum.AllDeleteOrphan, Inverse = true
.
Problem: When I am using a new session and I try and save it gives me the error A different object with same identifier was already associated with the session
. I have tried to use LINQ to return the list without using a new session by joining the other objects in the call but I'm not sure how to use ActiveRecordLinq<> when joining.
private Customer GetCustomer()
{
return (from x in ActiveRecordLinq.AsQueryable<Customer>()
where x.Customer_ID == ((Customer)lst_customers.SelectedItem).Customer_ID
select x).First();
}
Code that produces the error
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
}
Email Address Class
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
}
}
Division Customer 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
}
}
The way I finally got it to save after googling everywhere for an answer was to clear the Email_Addresses instead of clearing them.
SessionScope.Current.Evict(customer.EmailAddresses);
foreach (var t in lst_email.Items)
{
var temp = (Email_Address)t;
temp.Customer = customer;
customer.EmailAddresses.Add(temp);
}
Not sure why this worked though, if someone could explain that would be great. I posting this on here so that hopefully it will save some time for the next person encountering this error .
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With