2016-05-13 6 views
0

Ich benutze ASP.NET MVC 4 und ich habe eine Ansicht, wo ich ein paar Zeilen (Ausgaben) sehen kann und ich habe ein Kontrollkästchen neben jeder Zeile. Es gibt eine boolesche Eigenschaft mit dem Namen "Submitted" und eine DateTime-Eigenschaft namens DateSubmitted im Modell.Verwenden der Enumeration in Linq Query zum Aktualisieren mehrerer Zeilen in einer Datenbank

Ich habe eine Methode namens SubmitExpenses() und ich möchte nur die Zeilen, die überprüft werden, aktualisiert werden.

Die Spalten, die aktualisiert werden würden, sind DateSubmitted und Submitted.

Hier ist mein Modell:

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

} 

Hier werden die SubmitExpenses ist() -Methode:

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

} 

ist die Aussicht:

<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> 

} 

Ich weiß, wie alle Kosten vorzulegen das sind in dem angegebenen Datumsbereich (oder alle Ausgaben, die in der Ansicht angezeigt werden), aber ich bin mir nicht sicher, wie ich jedes r aktualisieren würde Nur für die Zeilen, die überprüft werden.

Vielen Dank.

Antwort

1

Zuerst als Nebenbei bemerkt, können Sie Abfrage Zusammensetzung verwenden, anstatt Ihre Abfrage jedes Mal zu wiederholen:

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

Nun zur Frage: Wenn ich Sie richtig verstehe, wollen Sie die Ausgaben aus der Datenbank heraus filtern Diese wurden in der Ansicht als Submitted markiert. Diese gefilterten Ausgaben sollten aktualisiert werden. Ein Weg, dies zu tun ist durch die mit denen aus der Sicht der Datenbankkosten Beitritt:

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

Durch die Verwendung von AsEnumerable auf der Datenbankabfrage, können Sie es mit einem lokalen Sequenz verbinden (expenses) als LINQ zu Objekten.

+0

Vielen Dank für die Stil Tipps. Ich wusste nicht, dass ich meinen Code so verkürzen könnte! Ich habe mich nur gefragt, woher das "e" in "x.e" kommt. – Sicypher

+1

Von 'new {e, user}'. –

+0

Die Variable 'joined' kommt als Null zurück. Muss ich etwas in der Ansicht machen, um die Variable zu setzen? – Sicypher

Verwandte Themen