从表中获取最大值,除非为null

时间:2016-01-07 15:09:35

标签: c# asp.net-mvc

我对C#和ASP.NET(以及一般的编程)都很陌生,并尝试做一些简单的练习。

我想做什么: 我想构建一个简单的MVC应用程序,其中记录将有版本。 那就是:给定一条记录,我即将通过“编辑”-View进行更改,此记录不会被覆盖。而是创建一个新记录(如新版本)。旧记录和新记录都具有相同的ItemId(不是主键!),它们将它们“语义地”链接在一起。为了知道哪个记录是较新的版本,较新的记录的VersionId为旧版本的VersionId的+1。

目前:我已开始致力于创建动作。新记录的VersionId值为1,而ItemId的值为DB加1中的最大ItemId - 除非DB中没有记录,否则ItemId应为1。

型号:

namespace HowToUpdate.Models
{
    public class ItemWithVersion
    {
        public int Id { get; set; }
        public int ItemNr { get; set; }
        public int VersionNr { get; set; }
        public string Name { get; set; }
    }
}

控制器操作:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Id,Name")] ItemWithVersion itemWithVersion)
    {
        if (ModelState.IsValid)
        {
            // set the ItemNr
            int currentMaxItemNr = db.ItemWithVersions.Max(i => i.ItemNr);
            itemWithVersion.ItemNr = currentMaxItemNr + 1;

            // set the VersionNr
            itemWithVersion.VersionNr = 1;

            db.ItemWithVersions.Add(itemWithVersion);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        return View(itemWithVersion);
    }

问题:当我运行localhost/ItemWithVersion/Create时,输入名称和提交的值,我收到以下错误: “转换为值类型'System.Int32'失败,因为具体化值为null。结果类型的泛型参数或查询必须使用可空类型。 来源错误:int currentMaxItemNr = db.ItemWithVersions.Max(i => i.ItemNr);

我试过了:

// set the ItemNr
int currentMaxItemNr = db.ItemWithVersions.Max(i => i.ItemNr);          
if (currentMaxItemNr == null)
{
    itemWithVersion.ItemNr = 1;
}
else
{
    itemWithVersion.ItemNr = currentMaxItemNr + 1;
}

现在错误似乎是int currentMaxItemNr = db.ItemWithVersions.Max(i => i.ItemNr);

int? currentMaxItemNr = db.ItemWithVersions.Max(i => i.ItemNr);var currentMaxItemNr = db.ItemWithVersions.Max(i => i.ItemNr);也不会有任何好处。

这可能是基本但我需要你的帮助! :) Thx。

5 个答案:

答案 0 :(得分:2)

您的if语句错误:

if (currentMaxItemNr != null) 目前检查currentMaxItemNr是否有值,如果有,请将其设为1

所以你的陈述应该是if (currentMaxItemNr == null)

修改

遗憾的是,我无法复制您的错误,但我确实检查过并发现在空Max()上调用List时会抛出异常。所以最好先拨打if (db.ItemWithVersions.Count() > 0)

这样您确定Max()将返回结果。如果该语句失败,您可以将currentMaxItemNr设置为0

答案 1 :(得分:1)

可能原因是Id被声明为int(不可为空,因此无法将null赋给id)。
请尝试以下操作。

 public int? Id { get; set; }

答案 2 :(得分:1)

在调用Max()方法之前,您需要确保表不为空。您可以使用Any()方法执行此操作。

int currentMaxItemNr = 0;
if (db.ItemWithVersions.Any())
{
    currentMaxItemNr = db.ItemWithVersions.Max(i => i.ItemNr);
}
itemWithVersion.ItemNr = currentMaxItemNr + 1;
// set the VersionNr
itemWithVersion.VersionNr = 1;

db.ItemWithVersions.Add(itemWithVersion);
db.SaveChanges();

答案 3 :(得分:0)

小心试试?

int currentMaxItemNr = db.ItemWithVersions.Max(i => i.ItemNr ?? 1);

如果currentMaxItemNr = 1 null ,则会返回i.ItemNr

答案 4 :(得分:0)

这是我将如何做到这一点。当您单击编辑时,我们运行:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Id,Name")] ItemWithVersion itemWithVersion)
{
    if (ModelState.IsValid)
    {
        // get the item with highest version
        ItemWithVersion item = db.ItemWithVersions.Where(i =>i.ItemNr == itemWithVersion.ItemNr).OrderByDescending(i => i.VersionNr).FirstOrDefault();
        //if item doesnt exist we need to create
        if(item == null)  {
           //get the last item with highest ItemNr
           ItemWithVersion lastitem = db.ItemWithVersions.OrderByDescending(i => i.ItemNr).FirstOrDefault();
           if(lastitem == null) {
             //if we didnt find a item, it means is the first item in the DB
             itemWithVersion.ItemNr = 1;
           } else {
             //increment the itemNr for the new Item
             itemWithVersion.ItemNr = lastitem.ItemNr + 1;
           }
           //set version to 1 since is the first version for this new ItemNr
           itemWithVersion.VersionNr = 1;
        } else {
            //if we found a item for the current ItemNr we increase the version for the new item
           itemWithVersion.VersionNr = item.VersionNr + 1;
        }

        db.ItemWithVersions.Add(itemWithVersion);
        db.SaveChanges();
        return RedirectToAction("Index");
    }

    return View(itemWithVersion);
}