剃刀视图中的2个后代模型的Foreach循环视图MVC c#

时间:2016-04-29 09:15:42

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

假设我有3个模型:

Account;
Expense;
Profit;

费用利润模型通过FK Acoount_Id链接到帐户

现在我希望有一个视图,我为每个帐户显示一个HTML表格,其中包含自己的移动(Profit和Expense数据表中的行)。我想让它们按插入日期排序,这是一个Profit和Expense表的字段。

如何在视图中实现Foreach?

像这样的逻辑:

Foreach (var item in ( (AccountModel.Profit join AccountModel.Expense).orderedByDate Desc) {
... Do stuff...
}

帐户模型:

namespace dBudget.Models
{
    using System;
    using System.Collections.Generic;

    public partial class Account
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public Account()
        {
            this.Expenses = new HashSet<Expense>();
            this.Profits = new HashSet<Profit>();
            this.UserAccounts = new HashSet<UserAccount>();
        }

        public int Id { get; set; }
        public string Name { get; set; }
        public int User_Id { get; set; }
        public System.DateTime DateCreated { get; set; }
        public bool Active { get; set; }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<Expense> Expenses { get; set; }
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<Profit> Profits { get; set; }
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<UserAccount> UserAccounts { get; set; }
    }
}

费用模型:

namespace dBudget.Models
{
    using System;
    using System.Collections.Generic;

    public partial class Expense
    {
        public int Id { get; set; }
        public double Value { get; set; }
        public string Description { get; set; }
        public System.DateTime Date { get; set; }
        public Nullable<int> Loan_Id { get; set; }
        public int User_Id { get; set; }
        public int Account_Id { get; set; }
        public System.DateTime DateCreated { get; set; }

        public virtual Account Account { get; set; }
        public virtual Loan Loan { get; set; }
        public virtual User User { get; set; }
    }
}

盈利模式:

namespace dBudget.Models
{
    using System;
    using System.Collections.Generic;

    public partial class Profit
    {
        public int Id { get; set; }
        public double Value { get; set; }
        public string Description { get; set; }
        public System.DateTime Date { get; set; }
        public Nullable<int> Loan_Id { get; set; }
        public int User_Id { get; set; }
        public int Account_Id { get; set; }
        public System.DateTime DateCreated { get; set; }

        public virtual Account Account { get; set; }
        public virtual Loan Loan { get; set; }
        public virtual User User { get; set; }
    }
}

2 个答案:

答案 0 :(得分:2)

从评论中,您需要所有费用和与一个地方的帐户相关的利润(Model / ViewModel)。

假设您现有的课程是:

public class Account
{
    public int Id { get; set; } // or account number

    // your rest of the properties
    public decimal AmountBalance { get; set; }

}


public class Expense
{
    public int Id { get; set; }
    public int AccountId { get; set; } // Foreign key
    public string Details { get; set; }
    public decimal Amount { get; set; }
}

public class Profit
{
    public int Id { get; set; }
    public int AccountId { get; set; } // Foreign key
    public string Details { get; set; }
    public decimal Amount { get; set; }
}

我们为模型添加一个类,如:

// Your view model
public class AccountModel
{
    public Account Account { get; set; }
    public List<Profit> Profits { get; set; }
    public List<Expense> Expenses { get; set; }
}

现在填充现有类的一些虚拟数据:

var accounts = new List<Account>
    {
        new Account {Id = 1, AmountBalance = 110},
        new Account {Id = 2, AmountBalance = 120},
    };

var expenses = new List<Expense>
    {
        new Expense {Id = 1, AccountId = 1, Amount = 10},
        new Expense {Id = 2, AccountId = 1, Amount = 40},
        new Expense {Id = 3, AccountId = 2, Amount = 50},
    };

var profits = new List<Profit>
    {
        new Profit {Id = 1, AccountId = 1, Amount = 20},
        new Profit {Id = 2, AccountId = 2, Amount = 30},
        new Profit {Id = 3, AccountId = 2, Amount = 60},
    };

然后我们按Profits

形成Expensesaccount number / Id的群组
// Form groups of expenses by the account number / id. Each group will have all the expenses belonging to the same account number / id
var expenseGroupsByAccount = expenses.GroupBy(expense => expense.AccountId).ToList();

// Form groups of profits by the account number / id. Each group will have all the profits belonging to the same account number / id
var profitGroupsByAccount = profits.GroupBy(profit => profit.AccountId).ToList();

最后,我们填充Model

// Now we can populate the AccountModel, which is essentially an account and all expenses & profits associated with it. 
var accountModels = new List<AccountModel>();
foreach (Account account in accounts)
{
    var accountModel = new AccountModel
        {
            Account = account,
            Profits =
                profitGroupsByAccount.Where(profitsGroup => profitsGroup.Key == account.Id)
                                     .SelectMany(g => g)
                                     .ToList(),
            Expenses = expenseGroupsByAccount.Where(expenseGroup => expenseGroup.Key == account.Id)
                                             .SelectMany(g => g)
                                             .ToList()
        };
    accountModels.Add(accountModel);
}

答案 1 :(得分:0)

将一个类添加到Models文件夹中,将其命名为Movement.cs。 该类将包含Movement的结构,其中包括所有的利润和费用表。

using System.Collections.Generic;

namespace dBudget.Models {

    public class Movement {
        public int Id { get; set; }
        public double Value { get; set; }
        public string Description { get; set; }
        public string Type { get; set; }
        public System.DateTime Date { get; set; }

        public List<Account> Accounts { get; set; }
    }

    public partial class Account {
        public double Balance { get; set; }
        public virtual ICollection<Movement> Movements { get; set; }
    }
}

向AccountController.cs文件添加新操作:

// GET: Account Movements
public ActionResult Movements(int? id) {
    if (id == null) {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    Account account = db.Accounts.Find(id);
    if (account == null) {
        return HttpNotFound();
    }

    //-- BEGIN SAMPLE DATA - DELETE WHEN YOU HAVE DATABASE FILLED
    var accounts = new List<Account> {
        new Account {Id = 1, Name = "Account 1"}
    };

    account = accounts.First();

    var profits = new List<Profit> {
        new Profit {Id = 1, Account_Id = 1, Value = 20, Description = "Profit 1", Date = DateTime.Now.AddMinutes(-60)},
        new Profit {Id = 2, Account_Id = 1, Value = 30, Description = "Profit 2", Date = DateTime.Now.AddMinutes(-120)},
        new Profit {Id = 3, Account_Id = 1, Value = 60, Description = "Profit 3", Date = DateTime.Now.AddMinutes(-180)},
    };
    account.Profits = profits;

    var expenses = new List<Expense> {
        new Expense {Id = 1, Account_Id = 1, Value = 10, Description = "Expense 1", Date = DateTime.Now.AddMinutes(-30)},
        new Expense {Id = 2, Account_Id = 1, Value = 40, Description = "Expense 2", Date = DateTime.Now.AddMinutes(-90)},
        new Expense {Id = 3, Account_Id = 1, Value = 200, Description = "Expense 3", Date = DateTime.Now.AddMinutes(-150)},
    };
    account.Expenses = expenses;
    //-- END SAMPLE DATA

    //-- BEGIN Fill Movements
    var movements = new List<Movement> { };

    foreach (Profit p in account.Profits) {

        var m = new Movement { Id = p.Id, Value = p.Value, Description = p.Description, Type = "Profit", Date = p.Date };
        movements.Add(m);

        //-- Add Profits sum to Balance
        account.Balance += p.Value;
    }

    foreach (Expense e in account.Expenses) {

        var m = new Movement { Id = e.Id, Value = e.Value, Description = e.Description, Type = "Expense", Date = e.Date };
        movements.Add(m);

        //-- Add Expenses sum to Balance
        account.Balance -= e.Value;
    }

    account.Movements = movements.OrderByDescending(x => x.Date).ToList();

    //-- END Fill Movements

    ViewBag.AccountName = account.Name;
    ViewBag.AccountBalance = account.Balance;
    return View(account.Movements);
}

将新视图添加到Views / Account文件夹,将其命名为Movements.cshtml,添加以下代码:(使用Value做了一些很酷的事情,有利润时为绿色,费用为红色,如果不需要则删除)

@model IEnumerable<dBudget.Models.Movement>

@{
    ViewBag.Title = ViewBag.AccountName + " : Movements";
}

<h2>@ViewBag.Title</h2>

<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Date)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Description)
        </th>
        <th style="text-align:right;">
            @Html.DisplayNameFor(model => model.Value)
        </th>
        <th style="text-align:right;"></th>
    </tr>

    @foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Date)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Description)
            </td>
            @if (item.Type.Equals("Profit")) {
                <td style="color:green; text-align:right;">
                    @Html.DisplayFor(modelItem => item.Value)
                </td>
            } else {
                <td style="color:red; text-align:right;">
                    - @Html.DisplayFor(modelItem => item.Value)
                </td>
            }
            <td style="text-align:right;">
                @Html.ActionLink("Edit", "Edit", new { id = item.Id }) |
                @Html.ActionLink("Delete", "Delete", new { id = item.Id })
            </td>
        </tr>
    }
</table>
<p><strong>Balance: @ViewBag.AccountBalance </strong></p>

然后访问yoursite / Accounts / Movements / 1 它必须是'1',因为它是演示部分中唯一插入的帐号,还记得吗?它在控制器中。不要忘记在数据库中添加一些值并在之后清理演示部分。