Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc ASP.NET MVC实体框架中DTO的最佳实践_Asp.net Mvc_Entity Framework - Fatal编程技术网

Asp.net mvc ASP.NET MVC实体框架中DTO的最佳实践

Asp.net mvc ASP.NET MVC实体框架中DTO的最佳实践,asp.net-mvc,entity-framework,Asp.net Mvc,Entity Framework,使用实体框架和DTO的最佳方式是什么 假设映射后,我有如下对象: Author int id sting name List<Book> books Book int id string name Author author int authorID 因为作者可以有很多书,所以我不想检索所有的书,比如我只对作者感兴趣 但有时我可能想得到一些作者和经过筛选的书或所有的书。 我可以使用多个查询authordtogetauthor

使用实体框架和DTO的最佳方式是什么

假设映射后,我有如下对象:

Author
    int id
    sting name
    List<Book> books

Book
    int id
    string name
    Author author
    int authorID
因为作者可以有很多书,所以我不想检索所有的书,比如我只对作者感兴趣

但有时我可能想得到一些作者和经过筛选的书或所有的书。 我可以使用多个查询
authordtogetauthor(intid)
列出getbook(intauthord)
。但这意味着要多次访问数据库

我的看法是:

  • 如果我在
    AuthorDTO
    字段
    列出书籍
    中,这项工作就可以完成。但有时我会将此列表保留为空,例如,如果我只列出作者。这意味着一些不一致,混乱和很多细节需要记住

  • Return
    Tuple
    可能有点混乱

  • 定义新的DTO

    AuthorAndBooksDTO
        AuthorDTO author
        List<BookDTO> books
    
    author和booksdto
    作者
    书目
    

  • 我认为,对所涉及的问题进行一些澄清,实际上可以解决您在这里的困惑

    首先也是最重要的一点,您的实体类是DTO。事实上,他们就是这样。它们是表示数据库中的表结构的类,以便可以将实体框架生成的查询中的数据映射到它们上。换句话说,它们实际上是传输数据的对象。微软和后来太多MVC开发人员的失败之处在于将它们与MVC模式所描述的大M模型混为一谈

    因此,使用实体框架返回实体的一个或多个实例,然后将其映射到另一个DTO类,最后在代码中使用它,这是完全没有意义的。您所做的只是创建一个毫无意义的抽象级别,它不向您的应用程序添加任何内容,而是另一个需要维护的内容

    就关系而言,这就是实体框架的惰性/渴望加载的原因。但是,为了利用它,代表关系的属性必须遵循一个非常具体的约定:

    public virtual ICollection<Book> Books { get; set; }
    

    我认为,对所涉及的问题进行一些澄清,实际上可以解决您在这里的困惑

    首先也是最重要的一点,您的实体类是DTO。事实上,他们就是这样。它们是表示数据库中的表结构的类,以便可以将实体框架生成的查询中的数据映射到它们上。换句话说,它们实际上是传输数据的对象。微软和后来太多MVC开发人员的失败之处在于将它们与MVC模式所描述的大M模型混为一谈

    因此,使用实体框架返回实体的一个或多个实例,然后将其映射到另一个DTO类,最后在代码中使用它,这是完全没有意义的。您所做的只是创建一个毫无意义的抽象级别,它不向您的应用程序添加任何内容,而是另一个需要维护的内容

    就关系而言,这就是实体框架的惰性/渴望加载的原因。但是,为了利用它,代表关系的属性必须遵循一个非常具体的约定:

    public virtual ICollection<Book> Books { get; set; }
    

    坚持使用sinlge AuthorTo并有选择地填充列表的问题在于,现在您必须跟踪该DTO的来源。书单上的书是没有水化的,还是这位作者根本就没有书?我是否必须返回控制器并调用不同的方法来获取同一DTO的不同状态?从消费者的角度来看,这缺乏明确性


    根据我的经验,我学习了使用更多DTO的方法,而不是试图重复使用一组基本DTO来表示多个不同的数据集。它需要更多的“样板”,必须在DTO和实体之间建立一大堆类似的DTO和映射,但最终,特殊性和清晰性使代码库更易于阅读和管理

    坚持使用单个authordo并有选择地填充列表的问题在于,现在您必须跟踪该DTO的来源。书单上的书是没有水化的,还是这位作者根本就没有书?我是否必须返回控制器并调用不同的方法来获取同一DTO的不同状态?从消费者的角度来看,这缺乏明确性


    根据我的经验,我学习了使用更多DTO的方法,而不是试图重复使用一组基本DTO来表示多个不同的数据集。它需要更多的“样板”,必须在DTO和实体之间建立一大堆类似的DTO和映射,但最终,特殊性和清晰性使代码库更易于阅读和管理

    我的第一个问题是问你为什么要首先创建DTO?另一端是否有消费者正在使用此数据?它是屏幕吗?你建造DTO只是为了建造DTO吗

    既然您将问题标记为MVC,我将假设您正在向视图发送数据。您可能需要一个ViewModel。此ViewModel应包含使用它的视图上显示的所有数据。然后使用实体框架填充视图模型。这可以通过使用投影的单个查询或复杂的查询来完成


    所以在所有这些胡言乱语之后。我想说你想要选择3

    我的第一个问题是问你为什么要首先创建DTO?另一端是否有消费者正在使用此数据?它是屏幕吗?你建造DTO只是为了建造DTO吗

    既然您将问题标记为MVC,我将假设您正在向视图发送数据。您可能需要一个ViewModel。此ViewModel应包含使用它的视图上显示的所有数据。然后使用实体框架填充视图模型。这可以通过使用投影的单个查询或复杂的查询来完成

    所以在所有这些胡言乱语之后。我想说你想要选择3

    Jus
    var author = db.Authors.Include(m => m.Books).SingleOrDefault(m => m.Id == id);
    
    public class BookViewModel{
        public int Id {get;set;}
        public string Name {get;set;}
    }
    public class AuthorViewModel{
        public int Id {get;set;}
        public string Name {get;set;}
        public List<BookViewModel> Books {get;set;} = new List<BookViewModel>();
    }
    
    public class AuthorsViewModel
    {
        public List<AuthorViewModel> Authors {get;set;} = new List<AuthorViewModel>();
    
        //add in this class other properties, like the filters used on the page...
    
        public void Load(){
            //here you can retrieve the data from your database. 
            //you could do like this:
            //step 1: retrieve data from DB via EF
            //step 2: fill in the Authors view models from the data at step 1
        }
    
    }
    
    //and in your controller you're calling the Load method to fill you're viewmodel with data from db. 
    public class AuthorsController{
        public ActionResult Index(){
            AuthorsViewModel model = new AuthorsViewModel();
            model.Load();
            return View(model);
        }
    }