ASP.NET MVC如何将FilePath传递到PeopleDB?

3
我是一个使用实体框架的ASP.NET新手。我有不同的模型,包括People、FileType和FilePath。我想通过从FilPath检索文件路径并在索引视图中显示像名称、年龄等数据来显示图像。我已经在详细视图中实现了这一点,但在索引视图页中,我收到了“值不能为空”的错误,这是由于PeopleDB中的FilePath为空造成的。
以下是我的代码,请帮忙。谢谢。

/Model/PeopleDB.cs

namespace MvcDemo.Models {
    public class PeopleDB
    {
        public PeopleDB()
        {
         this.FilePaths = new HashSet<FilePath>();
        }

        public int ID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
        public string Address { get; set; }
        public string Interests { get; set; }
        public ICollection<FilePath> FilePaths { get; set; }
    }


    public class PeopleDBContext : DbContext
    {
        public DbSet<FilePath> FilePaths { get; set; }
        public DbSet<PeopleDB> People { get; set; }      

    }

     }

/Model/FilePath.cs

 namespace Assessment_HC.Models
{        
    public class FilePath
    {
        public int FilePathId {get;set;}
        [StringLength(255)]
        public string FileName {get;set;}
        public FileType FileType {get;set;}
        public int PersonID {get;set;}
        public virtual PeopleDB Person {get;set;}
    }    
}

Moedel/FileType.cs

    namespace Assessment_HC.Models
{
    public enum FileType
    {
        Avatar = 1, Photo
    }
}

这里是用于索引视图的控制器

//Get: /People/Index
public ActionResult Index()
{
    return View(db.People.ToList());
}

在db.People.ToList()中,People.FilePath视图为空。

在控制器中,详细视图如下,我可以从中获取在详细页面上显示的图像:

// GET: /People/Details

public ActionResult Details(int id = 0)
{
    PeopleDB peopledb = db.People.Find(id);
    PeopleDB people = db.People.Include(i => i.FilePaths).SingleOrDefault(i => i.ID == id);
    if (peopledb == null)
    {
        return HttpNotFound();
    }
    return View(peopledb);
}

感谢您的帮助。如果您需要更多的代码,请让我知道。
2个回答

3

根据评论,您唯一需要做的是将PeopleDBFilePaths属性更改为virtual以与默认启用的Lazy Loading一起使用:

public virtual ICollection<FilePath> FilePaths { get; set; }

惰性加载默认是启用的,正如评论中所述,您没有更改它并且在您的上下文构造函数中没有关于惰性加载的内容,因此似乎问题出在您的 FilePaths 导航属性上,该属性不是虚拟的。

对于索引操作:

return View(db.People.ToList());

具体操作最好按照以下步骤进行:

var people = db.People.Where(x => x.ID == id).FirstOrDefault();
if (people == null)
{
    return HttpNotFound();
}
return View(people );    

无论如何,如果禁用懒加载,您应该使用Include将导航属性包含在结果中。在这种情况下,您可以在索引操作中使用以下方法加载数据:

db.People.Include(x => x.FilePaths).ToList()

或者

//Remember to add using System.Data.Entity;
db.People.Include("FilePaths").ToList() 

要禁用Lazy Loading,您可以:
db.Configuration.LazyLoadingEnabled = true;

或者在您的上下文构造函数中:

this.Configuration.LazyLoadingEnabled = false;

更多信息:

加载相关实体

惰性加载是指在第一次访问引用实体/实体集合的属性时,会自动从数据库中加载实体或实体集合的过程。使用POCO实体类型时,可以通过创建派生代理类型的实例,然后重写虚拟属性以添加加载钩子来实现惰性加载。


感谢您的快速回复。我刚试了一下,仍然出现了相同的错误,PeopleDB中的FilePath仍为空。 - Jialu Zhu
1
懒加载是否已启用或禁用?它的构造函数代码不在您发布的代码中。 - Reza Aghaei
我不认为我禁用了LazyLoading。 - Jialu Zhu
1
谢谢Reza,我将文件路径更改为虚拟路径后使其正常工作了。 - Jialu Zhu
@JialuZhu 不客气,顺便说一下,在StackOverflow上,当你发现一个答案有帮助时,你可以友好地接受它作为答案和/或投票支持它,以便将来更有帮助的其他用户:) - Reza Aghaei
显示剩余4条评论

2

我已经测试了这段代码,唯一需要的是启用Eager loading,使用Include方法:

    public ActionResult Index()
    {
        var _db = new ApplicationDbContext();
        var model = _db.People.Include("FilePaths").ToList();
        return View(model);
    }

在这种情况下,所有相关的文件路径都将被加载。
您还可以将FilePaths设置为虚拟路径:
public virtual ICollection<FilePath> FilePaths { get; set; }

并按照以下方式更改您的查询:

var model = _db.People.ToList();

在这两种情况下,所有相关的文件路径都将被加载。

1
通过将文件路径设置为虚拟路径,对我来说很有效。谢谢Sirwan。 - Jialu Zhu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接