【问题标题】:MVC 4 - Dictionary not savedMVC 4 - 字典未保存
【发布时间】:2013-05-31 10:37:52
【问题描述】:

我已将一些字典添加到实体“组合”中。其中的值不是由用户直接更新的,而是实体本身具有填充/刷新此字典的方法。

我正在从另一个控制器调用此刷新方法,就在返回操作之前:

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

通过调试,我可以看到 refreshDicts() 向 dict 添加了 6 个值,就像它应该做的那样。但是这些并没有被存储,尽管调用 db.SaveChanges() ...当我尝试访问另一个控制器中的 dict 时,我可以看到它是空的。

在尝试调用 refreshDicts()(将对象添加到投资组合中的列表)之前,我正在同一个 Controller 方法中对投资组合执行另一项操作,并且已正确保存。

怎么可能?感谢您的帮助!

更新

带有字典的班级组合

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>();
    }

控制器:

   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");
    }

我的背景:

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>();
    }   
}

我正在调用的 refreshDict 方法

    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));
            }
        }
    }
    ....

【问题讨论】:

    标签: asp.net asp.net-mvc entity-framework


    【解决方案1】:

    尝试指定您修改实体的框架:

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

    编辑

    看到更新后的代码后,您似乎正在尝试将Dictionary 对象直接保存到数据库中。无法使用实体框架将Dictionary 映射到数据库表。见this SO answer

    【讨论】:

    • 感谢您的提示,很遗憾它仍未保存。请查看我更新的问题,我已经从我的上下文和控制器中添加了代码。谢谢!!
    • 看起来您正试图将字典直接保存到数据库中。这个is not possible。我更新了答案,链接的答案对如何处理字典有一些建议。
    • 噢!谢谢你,真遗憾我没有找到那个问题..再次感谢!
    【解决方案2】:

    对于您所写的内容,我认为您有 2 个不同的 typeof(db) 对象。也就是说,您有 2 个dbContexts,您正在向其中一个添加对象并保存另一个。

    默认情况下dbContexts 跟踪实体,如果您从另一个调用保存,则添加的实体不会被此实例跟踪,因此不会被保存。 在您进行更改的上下文中致电.SaveChanges(),一切都应该正常

    更新:- 你的代码有问题。字典项目不能直接存储在数据库中。而是尝试将项目添加到表或 DbSet

    【讨论】:

    • 我得到了这样的投资组合参考:投资组合投资组合 = db.Portfolios.Single(x => x.GroupID == userGroupId);其中“db”是对我的上下文的唯一引用。那么应该只是typof(db)的一个对象,还是我在这里遗漏了什么??
    • 哦,在我试图访问字典的另一个控制器中,我正在使用 private myContext db = new myContext(); ,就像我在调用“refreshDicts()”的控制器中所做的那样..
    • Parv,你能看看我添加的代码吗?如果知道为什么没有保存更改,我将非常感激!
    • 在您写下的问题中,您在返回操作之前调用了 refreshDicts 函数。该代码在哪里?
    • 查看Controller部分的代码://字典刷新portfolio.refreshDicts(); db.Entry(portfolio).State = EntityState.Modified; // 保存并返回 db.SaveChanges(); return RedirectToAction("../Portfolio/Index");
    猜你喜欢
    • 1970-01-01
    • 2022-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多