0
votes

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

2
I tried :) not much to say - Fred Johnson
Update your DB context maybe? You know how to do that one? - Ben_Coding
Been sat here warey of sounding stupid, but it's probably inevitable ;) ... doesn't using (var db = new PrivateMessageContext()) at the top of the Send method take care of that? - Fred Johnson
what is the version of your EF? - Zafar

2 Answers

0
votes

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

0
votes

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.