简体   繁体   中英

Proper way to join tables (models) for an MVC View using EF, need to use in data list and CRUD opperations

I have a simple relational database for my project. I am trying to integrate a join between tables for a list view and then later to populate form data and a select list.

I have a Class for Teams and one for Locations, both sharing LocationId as a FK. I need to display the Team information and the NAME of the location based on the value of the LocationId in the Teams table. This should be easy, but I am new to EF and can't get it to work.

I created a ViewModel for the Teams class and added a list of "Location" as you will see in the code below.

The two problems I have are, no results for Location in the view (I do not know how to join this on LocationId anyway) so if it did display something it would be wrong. The second problem is that even though I have Location available in the View, I have no way to drill down to the Name.

My Locations class

public class Locations
{
    [Key]
    public int LocationId { get; set; }
    [Required(ErrorMessage = "Please enter a Location Name")]
    [MaxLength(50, ErrorMessage = "Name cannot exceed 50 characters")]
    public string Name { get; set; }
    public string Address { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    [Required]
    [Range(0, 99999, ErrorMessage = "Please enter a valid Zip Code")]
    public int ZipCode { get; set; }
    [Required(ErrorMessage = "Please enter a Phone Number")]
    [DataType(DataType.PhoneNumber)]
    [RegularExpression(@"^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$", ErrorMessage = "Please enter a valid Phone Number")]
    public string Telephone { get; set; }
    [Required(ErrorMessage = "Please enter an Email Address")]
    [RegularExpression(@"^([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$",
        ErrorMessage = "The Email Address you have Entered is Invalid")]
    public string Email { get; set; }        
    public string Website { get; set; }
    [Required]
    [Display(Name = "Is Active?")]
    public bool IsActive { get; set; }
}

My Teams Class

public class TeamsViewModel
{
    [Key]
    public int TeamId { get; set; }
    [Required(ErrorMessage = "Please enter a Team Name")]
    [MaxLength(50, ErrorMessage = "The Team Name cannot exceed 50 characters")]
    public string Name { get; set; }
    [Required]
    [Range(1, 99999, ErrorMessage = "Please Select a Home Location")]
    [Display(Name = "Home Location")]
    public int LocationId { get; set; }
    [Required]
    [Display(Name = "Is Active?")]
    public bool IsActive { get; set; }        
    public List<Locations> Location { get; set; }
}

My Controller Action for this page

public IActionResult Teams()
{
    var model = _teamRepository.GetAllTeams();
    return View("Teams", model);
}

And a portion of my view

@foreach (var team in Model)
{
    <tr class="tblRow">
        <td>@team.Name</td>
        **<td>@team.Location</td>**
        <td>
            <a class="btn btn-outline-info m-1"
               asp-controller="admin" asp-action="editTeam" asp-route-id="@team.Location">
                Edit
            </a>
        </td>
        <td>
            @using (Html.BeginForm("DeleteTeam", "Admin", team))
            {
                <input type="submit" value="Delete"
                       class="btn btn-outline-danger m-1"
                       onclick="return confirm('Are you sure you wish to delete this Team?');" />
            }
        </td>
        <td class="activeStatus" style="display:none;">
            @team.IsActive
        </td>
    </tr>
}

You can use Include function in linq to get location list related to TeamsViewModel.

 public IActionResult Teams()
        {
            var model = _context.TeamsViewModel.Include(x => x.Location).ToList();
             return View("Teams", model);
        }

In view, you need to add a foreach to loop location lists(team) to show the location name.

  @foreach (var team in Model)
    {
        @foreach (var location in team.Location)
        {
            <tr class="tblRow">
                <td>@team.Name</td>
                <td>@location.Name</td>
                <td>
                    <a class="btn btn-outline-info m-1"
                       asp-controller="Team" asp-action="editTeam" asp-route-id="@location.LocationId">
                        Edit
                    </a>
                </td>
                <td>
                    @using (Html.BeginForm("DeleteTeam", "Team", team))
                    {
                        <input type="submit" value="Delete"
                               class="btn btn-outline-danger m-1"
                               onclick="return confirm('Are you sure you wish to delete this Team?');" />
                    }
                </td>

                <td class="activeStatus" style="display:none;">
                    @team.IsActive
                </td>
            </tr>
        }

    }

Should be as simple as

var q = from t in db.Teams
        select new TeamsViewModel()
        {
          TeamId = t.TeamId,
          Name = t.Name,
          . . .
          Locations = t.Locations.ToList()
        };

var results = q.ToList();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM