I am getting the following error:
An unhandled exception of type 'System.InvalidOperationException'
occurred in EntityFramework.dll
Additional information: The model backing the 'PrivateMessageContext'
context has changed since the database was created. Consider using
Code First Migrations to update the database
(http://go.microsoft.com/fwlink/?
But why has it changed? All I want is to get the new message, check if the users have previous message history and either create a new message history or append their current...
I am trying to test the send method, so I want to print out the previous messages each time a new message is added
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity;
namespace CodeFirstNewDatabaseSample
{
class Program
{
static void Main(string[] args)
{
Console.Write("Enter message: ");
var message = Console.ReadLine();
var userFrom = "userFrom";
var userTo = "userTo";
Methods test = new Methods();
for(var i=0; i < 10; i++)
{
test.StoreMessage(userTo, userFrom, message);
Console.Write("Enter message: ");
message = Console.ReadLine();
}
}
}
public class PrivateMessageContext : DbContext
{
public DbSet<PrivateMessageHeader> PrivateMessages { get; set; }
}
public class PrivateMessageHeader
{
public PrivateMessageHeader() { this.Messages = new List<PrivateMessageDetail>(); }
public int PrivateMessageHeaderId { get; set; }
public DateTime TimeStamp { get; set; } // Date of the start of thread
public string User1 { get; set; }
public string User2 { get; set; } // this could be made to a list to allow multiples
public ICollection<PrivateMessageDetail> Messages { get; set; }
}
public class PrivateMessageDetail
{
public int PrivateMessageDetailId { get; set; }
public DateTime MessageDate { get; set; }
public string FromUser { get; set; } // Don't need ToUser, it's already in header
public string Message { get; set; }
public PrivateMessageHeader parent { get; set; }
}
public class Methods
{
public void StoreMessage(string userTo, string userFrom, string InputMessage)
{
using (var db = new PrivateMessageContext())
{
var collection = from pm in db.PrivateMessages select pm;
foreach(var msg in collection)
{
var user1 = msg.User1;
var user2 = msg.User2;
if ( (user1==userTo && user2==userFrom) || (user1==userFrom && user2==userTo))
{
var msgDetail = new PrivateMessageDetail();
msgDetail.FromUser = userFrom;
msgDetail.Message = InputMessage;
msgDetail.MessageDate = DateTime.Now;
msg.Messages.Add(msgDetail);
db.SaveChanges();
return;
}
}
// pair doesn't exist
var PrivateMessage = new PrivateMessageDetail();
PrivateMessage.MessageDate = DateTime.Now;
PrivateMessage.FromUser = userFrom;
PrivateMessage.Message = InputMessage;
var newCollection = new PrivateMessageHeader();
newCollection.TimeStamp = DateTime.Now;
newCollection.User1 = userTo;
newCollection.User2 = userFrom;
newCollection.Messages.Add(PrivateMessage);
db.PrivateMessages.Add(newCollection);
db.SaveChanges();
var iterator = 0;
// Display all messages from the database
foreach (var pmsg in db.PrivateMessages)
{
var query = pmsg;
var list = pmsg.Messages.ToList();
foreach (var item in list)
{
Console.WriteLine("msg" + iterator + ": " + item.ToString());
}
iterator++;
}
Console.ReadKey();
}
}
}
}
Many thanks
One of the sources I use for this issue is the Package Manager Console in VS2012. By using the Enable-Migrations command, along with the EnableAutomaticMigations flag, and then adding the Migration info into the project, I can update the database with any Code-First model changes that will not "break" the database, or my code. You won't have to manually add anything into the project, this is all done for you. If you forget to enable automatic migrations, you can manually edit this in the Configuration file that is added during this process. I believe that this process has been around since VS2008, but don't quote me on that. I have used this since VS2010 and has worked in both MVC and MVVM for both web and desktop. One of the articles I use on MSDN is here: http://msdn.microsoft.com/en-us/data/JJ591621.aspx, and you can also look for tutorials from John Galloway that explain this in detail.
Have you tried Database.SetInitializer<PrivateMessageContext>(null);?
Try to change your Context as follows.
public class PrivateMessageContext : DbContext
{
public DbSet<PrivateMessageHeader> PrivateMessages { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
Database.SetInitializer<PrivateMessageContext>(null);
}
}
More info here
Related
The part at the "invoiceUnit.Items.Add(itemOne);" I get an error. It says:
1. System.NullReferenceException: 'Object reference not set to an
instance of an object.'
2. PROGRAM_B2.Program.Order.Items.get returned null.
Also when I comment out that line of codes, I managed to get it run but the data in invoiceDataOut.xml is nothing. The serializer doesn't seem to be working.
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization;
namespace PROGRAM_B2
{
// This is the class that we want to serialize:.
[Serializable()]
public class Program
{
// Main class which is directly accessed
public class Order
{
public int InvoiceID { get; set; }
private DateTime _InvoiceDate { get; set; }
public string InvoiceDate {
get { return _InvoiceDate.ToString("d/m/yyyy"); }
set { _InvoiceDate = DateTime.ParseExact(value, "d/m/yyyy", CultureInfo.InvariantCulture); }
}
public int SellerID { get; set; }
public int BuyerID { get; set; }
public int OrderID { get; set; }
public List<Item> Items { get; set; }
public double ShippingCharges { get; set; }
public double InvoiceTotalCost { get; set; }
}
// Indirectly accessed class
public class Item
{
public int ItemID { get; set; }
public string ItemName { get; set; }
public string Description { get; set; }
public int Quantity { get; set; }
public double NewUnitPrice { get; set; }
}
static void Main(string[] args)
{
Order invoiceUnit = new Order();
// Simple Type - Main Data
invoiceUnit.InvoiceID = 0011995;
invoiceUnit.InvoiceDate = "12/5/2017";
invoiceUnit.SellerID = 0020;
invoiceUnit.BuyerID = 1231;
invoiceUnit.OrderID = 9021;
// An Item -Multiple
Item itemOne = new Item();
itemOne.ItemID = 0001;
itemOne.ItemName = "Apple Macbook Pro";
itemOne.Description = "The best professional laptop for professionals.";
itemOne.Quantity = 5;
itemOne.NewUnitPrice = 4950.50;
// Add Item
invoiceUnit.Items.Add(itemOne);
// An Item -Multiple
Item itemTwo = new Item();
itemTwo.ItemID = 0002;
itemTwo.ItemName = "Microsoft Surface Laptop";
itemTwo.Description = "The most versatile professional laptop for experts.";
itemTwo.Quantity = 10;
itemTwo.NewUnitPrice = 3500.90;
// Add Item
invoiceUnit.Items.Add(itemTwo);
// Simple Type - Footer Data
invoiceUnit.ShippingCharges = 7000.00;
invoiceUnit.InvoiceTotalCost = 19500.10;
// Create a new XmlSerializer instance with the type of the test class
XmlSerializer SerializerObj = new XmlSerializer(typeof(Program));
// Create a new file stream to write the serialized object to a file
TextWriter WriteFileStream = new StreamWriter(#"../../../invoiceDataOut.xml");
SerializerObj.Serialize(WriteFileStream, invoiceUnit);
// Cleanup
WriteFileStream.Close();
/*
The test.xml file will look like this:
<?xml version="1.0"?>
<TestClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SomeString>foo</SomeString>
<Settings>
<string>A</string>
<string>B</string>
<string>C</string>
</Settings>
</TestClass>
*/
// Test the new loaded object:
/*Console.WriteLine(invoiceUnit.someString);
foreach (string Setting in invoiceUnit.Settings)
{
Console.WriteLine(Setting);
}
Console.ReadLine();
*/
}
}
}
Please let me know how I can make it better.
I want to map a two tables in entity framework 6 and need some help! It is for my chat application; I need to map user conversations into the database. Both group and private messages. For this question however, if you help me with the private messaging mapping, I should hopefully work out the group by myself :) anyway....
Each user can talk to any other user. They however share the same data, which is where I am struggling a bit: how to set the keys to the exact same data without duplication. This is what I have so far:
**EDIT - new code *****
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity;
namespace CodeFirstNewDatabaseSample
{
static void Main(string[] args)
{
using(var db = new PrivateMessageContext())
{
Console.Write("Enter message: ");
var message = Console.ReadLine();
var userFrom = "userFrom";
var userTo = "userTo";
var messageDetail = new PrivateMessageDetail(MessageDate = DateTime.Now, FromUser = userFrom, message = message);
var pm = new PrivateMessageHeader { User1 = userFrom, User2 = userTo, TimeStamp = DateTime.Now };
pm.Messages.Add(messageDetail);
db.PrivateMessages.Add(pm);
db.SaveChanges();
// Display all Blogs from the database
foreach(var pmsg in db.PrivateMessages)
{
var query = pmsg;
Console.WriteLine(pmsg.Message);
}
Console.ReadKey();
}
}
}
public class PrivateMessage
{
public int PrivateMessageId { get; set; }
public string Message { get; set; }
public DateTime TimeStamp { get; set; }
// public int User1Id { get; set; }
public virtual string user1 { get; set; }
// public virtual User user1 { get; set; }
public virtual string user2 { get; set; }
//public int User1Id { get; set; }
// public virtual User user2 { get; set; }
}
public class User
{
public int UserId { get; set; }
public string UserName { get; set; }
}
public class PrivateMessageContext : DbContext
{
public DbSet<PrivateMessage> PrivateMessages { get; set; }
}
public class Send
{
/* void Send(userTo, userFrom, message)
{
using (var db = new PrivateMessageContext()) {
var query = from pm in db.PrivateMessages;
foreach(var msg in pm)
{
var user1 = msg.user1;
var user2 = msg.user2;
if ( (user1==userTo && user2==userFrom) || (user1==userFrom && user2==userTo))
{
msg.Message += message;
return;
}
else {
// pair doesn't exist
var PrivateMessage = new PrivateMessage { user1 = userFrom; user2 = userTo; TimeStamp = DateTime.Now; Message = message; };
db.PrivateMessages.Add(PrivateMessage);
db.SaveChanges();
}
}
}*/
}
}
I am now stuck on two things - how to make a callable class which checks if there is previous message history (the Send() ) and how to use the User username instead of strings...
Thank you
*update 3*
static void Main(string[] args)
{
using(var db = new PrivateMessageContext())
{
Console.Write("Enter message: ");
var message = Console.ReadLine();
var userFrom = "userFrom";
var userTo = "userTo";
var messageDetail = new PrivateMessageDetail(MessageDate = DateTime.Now, FromUser = userFrom, message = message);
var pm = new PrivateMessageHeader { User1 = userFrom, User2 = userTo, TimeStamp = DateTime.Now, Message = messageDetail };
db.PrivateMessages.Add(pm);
db.SaveChanges();
// Display all Blogs from the database
foreach(var pmsg in db.PrivateMessages)
{
var query = pmsg;
Console.WriteLine(pmsg.Message);
}
Console.ReadKey();
}
}
}
public class PrivateMessageContext : DbContext
{
public DbSet<PrivateMessageHeader> PrivateMessages { get; set; }
}
What you probably want is some kind of master/detail. What you would do is create a PrivateMessageHeader type, and this would contain the participants in the private message. Then you would have a PrivateMessageDetail type that would contain the actual messages. There would be a 1 to many association between Header and details.
So something like this:
public class PrivateMessageHeader {
public PrivateMessageHeader() { Messages = new List<PrivateMessageDetail>; }
public int PrivateMessageHeaderId {get;set;}
public DateTime ThreadTime {get;set;} // Date of the start of thread
public string User1 {get;set;}
public string User2 {get;set;} // this could be made to a list to allow multiples
public ICollection<PrivateMessageDetail> Messages {get;set;}
}
public class PrivateMessageDetail {
public int PrivateMessageDetailId {get;set;}
public DateTime MessageDate {get;set;}
public string FromUser {get;set;} // Don't need ToUser, it's already in header
public string Message {get;set;}
public PrivateMessageHeader parent {get;set;}
}
I wrote very simple class, that perfom data access.
It checks if line with that day exist in table and update her or create a new line.
public class DataAccessClass
{
public static DayWeather GetDayWeather(DateTime date)
{
try
{
using (var db = new Context())
{
var query =
(from day in db.DayWeather
where ((DateTime)day.DateOfDay).Date == date.Date
select new DayWeather((short)day.Temperature, (ushort)day.WindSpeed, (ushort)day.Pressure, (ushort)day.Humidity, day.Cloudiness, day.TypeRecip, (DateTime)day.DateOfDay)).First();
return query;
}
}
catch (Exception exp)
{
if (!EventLog.SourceExists("DataAccessSource"))
{
EventLog.CreateEventSource("DataAccessSource", "DataAccessErrorLog");
}
EventLog.WriteEntry("DataAccessSource", exp.Message);
throw new Exception("Problem with data get.");
}
}
public static void SaveDayWeather(DayWeather day)
{
try
{
using (var db = new Context())
{
var existingDay =
(from d in db.DayWeather
where ((DateTime)day.DateOfDay).Date == day.DateOfDay.Date
select d).SingleOrDefault<DayWeather>();
if (existingDay != null)
{
existingDay.Temperature = day.Temperature;
existingDay.WindSpeed = day.WindSpeed;
existingDay.Pressure = day.Pressure;
existingDay.Humidity = day.Humidity;
existingDay.Cloudiness = day.Cloudiness;
existingDay.TypeRecip = day.TypeRecip;
db.SaveChanges();
}
else
{
DayWeather newDay = new DayWeather();
newDay.DateOfDay = day.DateOfDay;
newDay.Temperature = day.Temperature;
newDay.WindSpeed = day.WindSpeed;
newDay.Pressure = day.Pressure;
newDay.Humidity = day.Humidity;
newDay.Cloudiness = day.Cloudiness;
newDay.TypeRecip = day.TypeRecip;
db.DayWeather.Add(newDay);
db.SaveChanges();
}
}
}
It use EF for generate database. The Contex class and class for save look like this:
public class DayWeather
{
public short Temperature { get; set; }
public ushort WindSpeed { get; set; }
public ushort Pressure { get; set; }
public ushort Humidity { get; set; }
public string Cloudiness { get; set; }
public string TypeRecip { get; set; }
public DateTime DateOfDay { get; set; }
public DayWeather(short Temperature, ushort WindSpeed, ushort Pressure, ushort Humidity, string Cloudiness, string TypeRecip, DateTime Date)
{
this.Temperature = Temperature;
this.WindSpeed = WindSpeed;
this.Pressure = Pressure;
this.Humidity = Humidity;
this.Cloudiness = Cloudiness;
this.TypeRecip = TypeRecip;
this.DateOfDay = Date;
}
public DayWeather()
{
}
}
internal class Context : DbContext
{
public DbSet<DayWeather> DayWeather { get; set; }
}
I call this methods by this code:
DataAccessClass.SaveDayWeather(new DayWeather(12, 12, 12, 12, "Yes", "rain", DateTime.Now));
DayWeather day = DataAccessClass.GetDayWeather(DateTime.Now);
Console.WriteLine(day.ToString());
Console.ReadKey();
It should generate new database, but error occurs. In message it write that can`t connect to the SQL Server.
Is somebody know what is wrong?
P.S. Sorry for my bad English.
P.P.S. I added EF by NuGet.
You can manually specify the connection string as follows
using (var db = new Context("connectionString"))
The default constructor looks up a connection string in the web.config with the same name as the derived context class Context.
If it fails to find one it defaults to
Data Source=.\SQLEXPRESS;
or
Data Source=(LocalDb)\v11.0;
depending on the version of sql server you are using.
I'm trying to create a simple event store using C# and [ServiceStack] Redis.
public class AggregateEvents
{
public Guid Id { get; set;}
public List<DomainEvent> Events { get; set; }
}
public abstract class DomainEvent { }
public class UserRegisteredEvent : DomainEvent
{
public Guid UserId { get; set; }
public string Name { get; set; }
}
public class UserPromotedEvent : DomainEvent
{
public Guid UserId { get; set; }
public string NewRole { get; set; }
}
if I do a roots.GetAll() I get an exception because the abstract class could not be instantiated. If I turn the base class into an interface instead, the Events object is null and the objects I stored in there get lost.
Any thoughts?
Edit 1
No joy using v3.03 and this code:
[Test]
public void foo()
{
var client = new RedisClient("localhost");
var users = client.GetTypedClient<AggregateEvents>();
var userId = Guid.NewGuid();
var eventsForUser = new AggregateEvents
{
Id = userId,
Events = new List<DomainEvent>()
};
eventsForUser.Events.Add(new UserPromotedEvent { UserId = userId });
users.Store(eventsForUser);
var all = users.GetAll(); // exception
}
Edit 2
Also not worked with this approach;
[Test]
public void foo()
{
var userId = Guid.NewGuid();
var client = new RedisClient("localhost");
client.As<DomainEvent>().Lists["urn:domainevents-" + userId].Add(new UserPromotedEvent {UserId= userId});
var users = client.As<DomainEvent>().Lists["urn:domainevents-" + userId];
foreach (var domainEvent in users) // exception
{
}
}
Can you try again with the latest version (v3.05+) of the ServiceStack Redis client:
https://github.com/ServiceStack/ServiceStack.Redis/downloads
The ServiceStack Json Serializer which the client uses has just added support for deserialization of Abstract/interface types which will be in the latest version of the client.
Note: this works by embedding __type information into the JSON payload which tells the serializer what concrete class it should deserialize into. It only embeds this information for Abstract/interface/object types. So you when you serialize you will need to cast to the abstract type, e.g:
redis.Store((DomainEvent)userPromoEvent);
or if adding to a list:
redis.As<DomainEvent>().Lists["urn:domainevents"].Add(userPromoEvent);
These examples now work as indicated by the newly added DomainEvents Unit Tests :)
[Test]
public void Can_Retrieve_DomainEvents()
{
var userId = Guid.NewGuid();
var client = new RedisClient("localhost");
client.FlushAll();
client.As<DomainEvent>().Lists["urn:domainevents-" + userId].Add(
new UserPromotedEvent { UserId = userId });
var users = client.As<DomainEvent>().Lists["urn:domainevents-" + userId];
Assert.That(users.Count, Is.EqualTo(1));
var userPromoEvent = (UserPromotedEvent)users[0];
Assert.That(userPromoEvent.UserId, Is.EqualTo(userId));
}
[Test]
public void Can_from_Retrieve_DomainEvents_list()
{
var client = new RedisClient("localhost");
var users = client.As<AggregateEvents>();
var userId = Guid.NewGuid();
var eventsForUser = new AggregateEvents
{
Id = userId,
Events = new List<DomainEvent>()
};
eventsForUser.Events.Add(new UserPromotedEvent { UserId = userId });
users.Store(eventsForUser);
var all = users.GetAll();
}
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 .
The evict removes that specific "Email_Address" reference from the NHibernate first level cache.
From customer.EmailAddresses you have removed all the email address in NHibernate first level cache.
You are then obtaining items from list of emails in lst_email and adding them into the EmailAddress for the customer as new objects.