peter
peter

Reputation: 2113

MVC 4 - Dictionary not saved

I've added some Dictionaries to the entity "portfolio". The values therein are not updated directly by the user, rather the entity itself has a method to fill / refresh this dictionary.

I'm calling this refresh method from another Controller, right before the return action:

..
portfolio.refreshDicts();
db.SaveChanges();

By debugging, I can see that refreshDicts() adds 6 values to the dict, just as it should. But these are not getting stored, though calling db.SaveChanges() ... When I try to access a dict in another controller, I can see that it is empty.

I'm performing another operation on portfolio in the same Controller method just some steps before trying to call refreshDicts() (adding an object to a list in portfolio) and this is saved correctly.

How can that be? Thank you for your help!

Update

Class Portfolio with the Dictionaries

public class Portfolio
{
    [Key]
    public int ID { get; set; }
    public string GroupID { get; set; }

    public virtual List<KassenwirksamesEreignis> KassenwirksameEreignisse { get; set; }
    public virtual List<InternMsg> InterneNachrichten { get; set; }
    public virtual List<StockPosition> StockPositions { get; set; }
    public virtual List<BondPosition> BondPositions { get; set; }
    public virtual List<FuturePosition> FuturePositions { get; set; }
    public virtual List<OptionPosition> OptionPositions { get; set; }
    public virtual List<FondsPosition> FondsPositions { get; set; }
    public virtual List<Regelereignis> RegelEreignisse { get; set; }

    public Dictionary<DateTime, double> FondsVolumenDict { get; set; }
    public Dictionary<DateTime, double> KasseDict { get; set; }
    public Dictionary<DateTime, double> StockDict { get; set; }
    public Dictionary<DateTime, double> OptionDict { get; set; }
    public Dictionary<DateTime, double> FutureDict { get; set; }
    public Dictionary<DateTime, double> FondsDict { get; set; }
    public Dictionary<DateTime, double> BondDict { get; set; }

    public Portfolio()
    {
        FondsVolumenDict = new Dictionary<DateTime, double>();
        KasseDict = new Dictionary<DateTime, double>();
        StockDict = new Dictionary<DateTime, double>();
        OptionDict = new Dictionary<DateTime, double>();
        FutureDict = new Dictionary<DateTime, double>();
        FondsDict = new Dictionary<DateTime, double>();
        BondDict = new Dictionary<DateTime, double>();
    }

Controller:

   public ActionResult Create(StockPosition position)
    {
        if (ModelState.IsValid)
        {
            // find user's portfolio
            string currentUser = User.Identity.Name;
            string userGroupId = db.UserProfiles.Single(x => x.UserName == currentUser).GroupId;
            Portfolio portfolio = db.Portfolios.Single(x => x.GroupID == userGroupId);

            // add Stock to portfolio
            position.PortfolioID = portfolio.ID;
            db.StockPositions.Add(position);

            // book costs 
            var ke = new KassenwirksamesEreignis();
            ke.Art = "Kauf";
            ke.Bezeichnung = position.Bezeichnung;
            ke.Date = DateTime.Now;
            ke.Wert = Math.Round((-1.0) * (position.Menge * position.Kaufpreis), 2);
            portfolio.KassenwirksameEreignisse.Add(ke);

            // Dictionaries refreshen
            portfolio.refreshDicts();
            db.Entry(portfolio).State = EntityState.Modified;

            // Save & Back
            db.SaveChanges();
            return RedirectToAction("../Portfolio/Index");
        }
        return RedirectToAction("../Portfolio/Index");
    }

my Context:

public class PlanspielContext : DbContext
{
    public DbSet<Portfolio> Portfolios { get; set; }
    public DbSet<UserProfile> UserProfiles { get; set; }
    public DbSet<GlobalMsg> GlobalNachrichten { get; set; }
    public DbSet<InternMsg> InterneNachrichten { get; set; }
    public DbSet<Price> Prices { get; set; }
    public DbSet<KassenwirksamesEreignis> KassenwirksameEreignisse { get; set; }
    public DbSet<Zinsanspruch> Zinsansprüche { get; set; }
    public DbSet<StockPosition> StockPositions { get; set; }
    public DbSet<OptionPosition> OptionPositions { get; set; }
    public DbSet<FuturePosition> FuturePositions { get; set; }
    public DbSet<BondPosition> BondPositions { get; set; }
    public DbSet<FondsPosition> FondsPositions { get; set; }
    public DbSet<Regelereignis> Regelereignisse { get; set; }

    // Am not sure if i need those here .. ?
    //public Dictionary<DateTime, double> FondsVolumenDict { get; set; }
    //public Dictionary<DateTime, double> KasseDict { get; set; }
    //public Dictionary<DateTime, double> StockDict { get; set; }
    //public Dictionary<DateTime, double> OptionDict { get; set; }
    //public Dictionary<DateTime, double> FutureDict { get; set; }
    //public Dictionary<DateTime, double> FondsDict { get; set; }
    //public Dictionary<DateTime, double> BondDict { get; set; }


    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
    }   
}

the refreshDict method i'm calling

    public void refreshDicts()
    {
        refreshBondDict();
        refreshFondsDict();
        refreshFutureDict();
        refreshOptionDict();
        refreshStockDict();
        refreshKasseDict();
        refreshFondsVolumenDict();
    }

    public void refreshFondsDict()
    {
        DateTime today = DateTime.Now;

        for ( var i = - 4; i <= 1; i++)
        {
            DateTime currentDay = today.AddDays(i).Date;

            if (this.FondsDict.ContainsKey(currentDay))
            {
                this.FondsDict[currentDay] = getFondsValue(currentDay);
            }
            else
            {
                this.FondsDict.Add(currentDay, getFondsValue(currentDay));
            }
        }
    }
    ....

Upvotes: 0

Views: 354

Answers (2)

Parv Sharma
Parv Sharma

Reputation: 12705

For what you have written i think you have 2 different Objects of typeof(db). That is to say you have 2 dbContexts and you are adding objects to one and saving the other.

By default dbContexts track the entities and hance if you call save from another the added entities are not tracked by this instance and therefore are not saved. call .SaveChanges() on the context in which your are making changes and everything should work fine

UPDATE:- there is some problem with your code. The Dictionary Items cannot be stores directly in the database. instead try adding the items to a table or to a DbSet

Upvotes: 0

dlebech
dlebech

Reputation: 1839

Try specifying to the framework that you modified the entity:

..
portfolio.refreshDicts();
db.Entry(portfolio).State = EntityState.Modified;
db.SaveChanges();

Edit

After seeing the updated code, it looks like you are trying to save the Dictionary objects directly to the database. It is not possible to map a Dictionary to a database table with Entity Framework. See this SO answer.

Upvotes: 2

Related Questions