【问题标题】:How to Use Enumeration within Linq Query to Update Multiple Rows in a Database如何在 Linq 查询中使用枚举更新数据库中的多行
【发布时间】:2016-09-10 03:46:47
【问题描述】:

我正在使用 ASP.NET MVC 4,我有一个视图,我可以在其中看到几行(费用),并且每行旁边都有一个复选框输入。模型中有一个名为“Submitted”的布尔属性和一个名为 DateSubmitted 的 DateTime 属性。

我有一个名为 SubmitExpenses() 的方法,我只想更新“检查”的行。

要更新的列是 DateSubmitted 和 Submitted。

这是我的模型:

public class Expense
{
    public Expense() { }

    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int ExpenseId { get; set; }

    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
    [Display(Name = "Date Submitted")]
    public DateTime? DateSubmitted { get; set; }

    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
    [Display(Name = "Expense Date")]
    public DateTime? ExpenseDate { get; set; }

    [Display(Name = "Submitted?")]
    public bool Submitted { get; set; }

    [Required]
    [Display(Name = "Name")]
    public int UserId { get; set; }
    [ForeignKey("UserId")]
    public virtual UserProfile UserProfile { get; set; }

}

这里是 SubmitExpenses() 方法:

public ActionResult SubmitExpenses(List<Expense> expenses, DateTime? expenseDate = null, DateTime? expenseDate2 = null, int? userId = 0)
{
    expenseDate = (DateTime)Session["FirstDate"];
    expenseDate2 = (DateTime)Session["SecondDate"];

    if (expenseDate == null || expenseDate2 == null)
    {
        expenseDate = DateTime.Now.AddMonths(-1);
        expenseDate2 = DateTime.Today;
    }

    string currentUserId = User.Identity.Name;

    var query = from e in db.Expenses
                join user in db.UserProfiles on e.UserId equals user.UserId
                where user.UserName == currentUserId && (e.ExpenseDate >= expenseDate && e.ExpenseDate <= expenseDate2) && e.DateSubmitted == null
                orderby e.ExpenseDate descending
                select e;

    if (User.IsInRole("admin") && userId != 0)
    {

        query = from e in db.Expenses
                join user in db.UserProfiles on e.UserId equals user.UserId
                where user.UserId == userId && e.ExpenseDate >= expenseDate && e.ExpenseDate <= expenseDate2 && e.DateSubmitted == null
                orderby e.ExpenseDate descending
                select e;
    }
    else if (User.IsInRole("admin"))
    {
        query = from e in db.Expenses
                join user in db.UserProfiles on e.UserId equals user.UserId
                where e.ExpenseDate >= expenseDate && e.ExpenseDate <= expenseDate2 && e.DateSubmitted == null
                orderby e.ExpenseDate descending
                select e;
    }


    foreach (Expense exp in query)
    {
        exp.DateSubmitted = DateTime.Today;
    }

    try
    {
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    catch (Exception e)
    {
        Console.WriteLine(e);
        return RedirectToAction("Submit");
    }

}

这里是视图:

<table>
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.DateSubmitted)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.ExpenseDate)
        </th>

        @if (User.IsInRole("admin"))
        {
            <th>
                @Html.DisplayNameFor(model => model.UserProfile.UserName)
            </th>
        }
        <th></th>
    </tr>
    <tr>
        <td>
            <b>Select All:</b>
            <br />
            <input type="checkbox" name="expense" value="Expense" id="selectAllCheckboxes" class="expenseCheck">
        </td>
    </tr>
    @foreach (var item in Model)
    {
        <tr>
            <td class="submitCheck">
                @Html.DisplayFor(modelItem => item.Submitted)
            </td>

            <td>
                @Html.DisplayFor(modelItem => item.DateSubmitted)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.ExpenseDate)
            </td>

            @if (User.IsInRole("admin"))
            {
                <td>
                    @Html.DisplayFor(modelItem => item.UserProfile.UserName)
                </td>
            }
        </tr>
    }

</table>

 @Html.ActionLink("Submit Expenses", "SubmitExpenses")

 @section scripts {
<script type="text/javascript">


    $("#selectAllCheckboxes").click(function () {
        $('.submitCheck input:checkbox').not(this).prop('checked', this.checked);
    });

    $('.submitCheck input:checkbox').prop('disabled', false);


</script>

}

我知道如何提交指定日期范围内的所有费用(或视图中显示的所有费用),但我不确定如何仅针对选中的行更新每一行。

谢谢。

【问题讨论】:

    标签: c# asp.net-mvc entity-framework linq asp.net-mvc-4


    【解决方案1】:

    首先,顺便说一句,您可以使用查询组合而不是每次都重复查询:

    var query = from e in db.Expenses
                join user in db.UserProfiles on e.UserId equals user.UserId
                where e.ExpenseDate >= expenseDate && e.ExpenseDate <= expenseDate2 && e.DateSubmitted == null
                orderby e.ExpenseDate descending
                select new { e, user };
    
    if (User.IsInRole("admin") && userId != 0)
    {
        query = query.Where(x => x.user.UserId == userId);
    }
    else if (!User.IsInRole("admin"))
    {
        query = query.Where(x => x.user.UserName == currentUserId);
    }
    

    现在的问题是:如果我对您的理解正确,您想从数据库中过滤掉视图中标记为Submitted 的费用。这些过滤后的费用应该更新。一种方法是将数据库费用与视图中的费用连接起来:

    var joined = from dbExpense in query.Select(x => x.e).AsEnumerable()
                 join localExpense in expenses on dbExpense.ExpenseId equals localExpense.ExpenseId
                 where localExpense.Submitted
                 select dbExpense;
    
    foreach (Expense exp in joined)
    {
        exp.DateSubmitted = DateTime.Today;
    }
    

    通过在数据库查询中使用AsEnumerable,您可以将其与本地序列 (expenses) 作为 LINQ to 对象连接。

    【讨论】:

    • 感谢您的风格提示。我不知道我可以这样缩短我的代码!我只是想知道'x.e'中的'e'来自哪里。
    • 来自new { e, user }
    • “joined”变量返回为空。我需要在视图中做些什么来设置变量吗?
    • joined 为空?我无法想象,因为返回可枚举的 LINQ 查询的结果永远不会为空。还是空的?
    • expenses 不为空吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多