显示由外键引用到用户配置文件表的表中的项目列表

Posted

技术标签:

【中文标题】显示由外键引用到用户配置文件表的表中的项目列表【英文标题】:show list of items from a table that is referenced by foreign key to a userprofile table 【发布时间】:2016-09-04 18:47:11 【问题描述】:

我对 MVC5 非常陌生,正在尝试组合一个小型待办事项列表应用程序。我创建了一个包含用户名和密码的 UserLogin 表,以及一个包含有关用户的所有其他信息的 UserProfile 表。这些表和相关功能我工作得很好。用户可以注册、登录、注销,适用的表格也会更新。

我还有一个包含用户想要添加的项目的待办事项列表。这是我遇到麻烦的地方。我无法弄清楚如何引用特定用户并显示特定于该用户的 todolist 表信息。

账户管理员:

using MyToDoListApplication.Models.EntityManager;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using ToDoListApplicationNew.Models.DB;
using ToDoListApplicationNew.Models.ViewModel;

namespace ToDoListApplicationNew.Controllers

    public class AccountController : Controller
    
        // GET: Account
        public ActionResult Index()
        
            return View();
        

        #region signup methods
        // Get method for signup page
        public ActionResult SignUpPage()
        
            return View();
        

        // Post method for signup page - post to db
        [HttpPost]
        // Pass in the UserSign up model object to be built
        public ActionResult SignUpPage(UserSignUp USUV)
        
            // Form is filled out and then method is entered
            if (ModelState.IsValid)
            
                // Form is filled out and database connection is established if form is valid
                UserProfileManager UPM = new UserProfileManager();

                if (!UPM.isLoginReal(USUV.Username))
                
                    // data access . adduseraccount from entity manager (where model objects are built)
                    UPM.AddUserAccount(USUV);
                    FormsAuthentication.SetAuthCookie(USUV.FirstName, false);
                    return RedirectToAction("Welcome", "Home");
                
                else
                

                
            
            return View();
        
        #endregion

        public ActionResult Login()
        
            return View();
        

        [HttpPost]
        public ActionResult Login(UserLoginView ULV, string returnURL)
        
            if(ModelState.IsValid)
            
                UserProfileManager UPM = new UserProfileManager();
                //retrive the password using the GetUserPassword() from UserProfileManager
                // This will pass the user name to the gup method and if the username and password exist
                // it will redirect the user to the welcome page.
                string password = UPM.GetUserPassword(ULV.Username);

                // If password is wrong or blank, catch with error message to user
                if(string.IsNullOrEmpty(password))
                
                    ModelState.AddModelError("", "The user login or password provided is incorrect");
                
                else
                
                    if(ULV.Password.Equals(password))
                    
                        FormsAuthentication.SetAuthCookie(ULV.Username, false);
                        return RedirectToAction("_UserHome", "Account");
                    
                    else
                    
                        ModelState.AddModelError("", "The password provided is incorrect");
                    
                
            
            return View();
        

        [Authorize]
        public ActionResult SignOut()
        
            FormsAuthentication.SignOut();
            return RedirectToAction("Index", "Home");
        

        #region UserHome 
        // After Login User is redirected to the _UserHome.cshtml view
        // This is where listItems should be showing up
        // MyList viewModel
        public ActionResult UserHome()
        
            if (Session["UserLoginID"] != null)
            
                using (ToDoDBEntities db = new ToDoDBEntities())
                
                    return View(db.MyListItems.ToList());
                
            
            else
            
                return RedirectToAction("LogIn");
            
        

        #endregion
    

这是我的实体连接管理类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using ToDoListApplicationNew.Models.DB;
using ToDoListApplicationNew.Models.ViewModel;

namespace MyToDoListApplication.Models.EntityManager

    public class UserProfileManager
    
        public void AddUserAccount(UserSignUp newUser)
        
            // create database connection
            using (ToDoDBEntities db = new ToDoDBEntities())
            
                // Collect viewmodel data
                // Here building goes by object type and not foregin key relationship
                UserLogin UL = new UserLogin();
                UL.Username = newUser.Username;
                UL.Password = newUser.Password;

                // Add the UserLogin object I just built to the database
                db.UserLogins.Add(UL);
                db.SaveChanges();

                UserProfile UP = new UserProfile();
                // establish connection to UL by establishing foreign key relationship
                UP.UserLoginID = UL.UserLoginID;
                // Now add the new table properties to the new object
                UP.FirstName = newUser.FirstName;
                UP.LastName = newUser.LastName;
                UP.CreationDate = newUser.CreationDate;
                UP.Email = newUser.Email;

                // Add UserProfile object to databse and save changes
                db.UserProfiles.Add(UP);
                db.SaveChanges();
            
        

        //Check if user is real before login is allowed
        public bool isLoginReal(string LoginName)
        
            using (ToDoDBEntities DB = new ToDoDBEntities())
            
                // Return the user from the DB whose login name matches the LoginName string passed in as perameter
                return DB.UserLogins.Where(o => o.Username.Equals(LoginName)).Any();
            
        

        // Check if password exists
        public string GetUserPassword(string loginName)
        
            using (ToDoDBEntities db = new ToDoDBEntities())
            
                // retrieves user by comparing the username to the loginname passed in as a perameter
                var user = db.UserLogins.Where(o => o.Username.ToLower().Equals(loginName));
                if (user.Any())
                    return user.FirstOrDefault().Password;
                else
                    return string.Empty;
            
        
    

这是我的 UserHome 视图。我想要做的是让用户在登录后重定向到这里并让他们的待办事项列表显示在此页面上

@model IEnumerable<ToDoListApplicationNew.Models.DB.MyListItem>

@
    ViewBag.Title = "UserHome";


<h2>UserHome</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.ItemDate)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Item)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.ItemImportance)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.UserProfile.FirstName)
        </th>
        <th></th>
    </tr>

@foreach (var item in Model) 
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.ItemDate)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Item)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.ItemImportance)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.UserProfile.FirstName)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new  id=item.MyToDoListID ) |
            @Html.ActionLink("Details", "Details", new  id=item.MyToDoListID ) |
            @Html.ActionLink("Delete", "Delete", new  id=item.MyToDoListID )
        </td>
    </tr>


</table>

我还附上了数据库设计的图片。enter image description here

所以,我的登录和注册功能非常好用。我最初只是让他们重定向到一个“欢迎”页面,该页面基本上说你好,欢迎。但这只是在我测试登录时。现在,我为待办事项添加了第三张表。我更新了 edmx。我也有这个我目前没有使用的视图模型(虽然我知道如何做到这一点,但我还是构建了它:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;

namespace ToDoListApplicationNew.Models.ViewModel

    public class userListViewModel
    
        [Key]
        public int MyToDoListID  get; set; 

        public int UserProfileID  get; set; 

        [DataType(DataType.DateTime)]
        [Display(Name =" Date of input")]
        public DateTime ItemDate  get; set; 

        [Required(ErrorMessage = "*")]
        [Display(Name ="New Item")]
        public string Item  get; set; 

        [Required(ErrorMessage = "*")]
        [Display(Name ="Importance level (1 - 10")]
        public int ItemImportance  get; set; 
    

我非常感谢任何帮助。如果有什么不明白的地方请告诉我,我会尽力解释。

干杯,

【问题讨论】:

【参考方案1】:

您应该将此导航属性添加到您的 userListViewModel 类中:

public UserProfile UserProfile get; set;

在此之后视图应该可以工作(cshtml文件)。

但假设您使用 EntityFramework,另一个问题可能是您的导航属性为空。 尝试像这样更改 UserHome 操作:

public ActionResult UserHome()

    if (Session["UserLoginID"] != null)
    
        using (ToDoDBEntities db = new ToDoDBEntities())
        
            // Include fetches the data behind navigation properties
            return View(db.MyListItems.Include(x => x.UserProfiles).ToList());
        
    
    else
    
        return RedirectToAction("LogIn");
    

【讨论】:

以上是关于显示由外键引用到用户配置文件表的表中的项目列表的主要内容,如果未能解决你的问题,请参考以下文章

数据库表关系及配置

多表操作

休眠。如何将条目添加到具有来自 Hibernate 中 2 个不同表的 2 个外键的表中?

如何在Laravel中查看外键中的表字段

外键约束

外键约束