Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.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
C# 自动映射为T类型初始化_C#_Entity Framework_Automapper - Fatal编程技术网

C# 自动映射为T类型初始化

C# 自动映射为T类型初始化,c#,entity-framework,automapper,C#,Entity Framework,Automapper,我希望有一个通用的方法从数据库中获取数据,并传递输出数据应该是什么样子的模型 我写了一个简单的方法: public IEnumerable<T> GetUsers<T>() { Mapper.Initialize(cfg => cfg.CreateMap<IQueryable<User>, IQueryable<T>>()); return OnConnect<IEnumerable<

我希望有一个通用的方法从数据库中获取数据,并传递输出数据应该是什么样子的模型

我写了一个简单的方法:

public IEnumerable<T> GetUsers<T>()
{
    Mapper.Initialize(cfg =>
         cfg.CreateMap<IQueryable<User>, IQueryable<T>>());

    return OnConnect<IEnumerable<T>>(db =>
    {
        return db.Users.ProjectTo<T>().ToList();
    });
}
public IEnumerable GetUsers()
{
Mapper.Initialize(cfg=>
CreateMap());
返回OnConnect(数据库=>
{
返回db.Users.ProjectTo().ToList();
});
}
现在我希望我能做到这一点:

var users = repo.GetUsers<UserViewModel>(); // it should be IEnumerable<UserViewModel>
var anotherUsers = repo.GetUsers<AnotherUserViewModel>(); // it should be IEnumerable<AnotherUserViewModel>
var users=repo.GetUsers();//它应该是数不清的
var anotherUsers=repo.GetUsers();//它应该是数不清的
但我无法再次初始化
自动映射器。我应该怎么做才能让它工作

  • 每次应用程序启动仅初始化自动映射一次
  • 在设计代码时,您应该知道可以从
    User
    映射哪些类型。在这种情况下,您可以在启动时注册所有类型,如下所示:

        Mapper.Initialize(cfg => {
                cfg.CreateMap<User, UserDto1>();
                cfg.CreateMap<User, UserDto2>();
                ...
                cfg.CreateMap<User, UserDtoN>();
            });
    
    Mapper.Initialize(cfg=>{
    CreateMap();
    CreateMap();
    ...
    CreateMap();
    });
    
  • 即使你能做到这一点——尝试将
    用户
    映射到
    订单
    也没有意义,但你的架构设计将提供这种可能性

  • 如果您仍然想这样做(就像我在注释中写的那样),您可以添加某种标记属性,例如-MappableFrom(Type from),标记可以在automapper范围内使用的所有DTO对象。然后在应用程序初始化时,扫描程序集以查找包含该属性的所有类型,并在Automapper中注册

  • 您可以使用配置文件创建所有遵循此链接的映射器

    另一种方法是,通过使用某种命名约定,可以在静态构造函数中初始化所需的所有映射

    在下面的代码中,我将从相同的对象类型映射到相同的对象类型

    // Data or View Models
    
    public class AddressViewModel : BaseViewModel
    {
        public string Address {get;set;}
        public AddressViewModel()
        {
            this.Address ="Address";
        }
    
    }
    
    public class UserViewModel : BaseViewModel
    {
        public string Name {get;set;}
        public UserViewModel()
        {
            this.Name ="Name";
        }
    }
    public class BaseViewModel
    {
    
    }
    
    存储库——这里我使用的是您应该在这里创建的相同视图模型

    public class CrudRepo
    {
         public IEnumerable<T> GetData<T>() where T : class, new ()
         {
            var data = new List<T> { new T() };
            return AutoMapper.Mapper.Map<IEnumerable<T>>(data);
         }
    }
    
    现在,您可以创建crud存储库的实例并获取映射项

        var userRepo = new CrudRepo();
    
        var users = userRepo.GetData<UserViewModel>();
        var address = addressRepo.GetData<AddressViewModel>();
    
    var userRepo=new crudepo();
    var users=userRepo.GetData();
    var address=addressRepo.GetData();
    

    注意
    :只要属性名称和类型相同,数据将被映射,否则您必须创建FormMember

    如果我有100个视图模型,我必须写100行初始化?这太奇怪了。@dafie在这种情况下,您可以添加某种标记属性,例如-
    MappableFrom(键入from)
    。然后在初始化时扫描程序集以查找包含该属性的所有类型,并在automapper中注册。。。这也很奇怪hell@Raphael不,100个视图模型,每个模型代表不同的东西。在1页上,我只需要有用户的
    Id
    电子邮件
    。第二,我需要有
    Id
    Name
    LastName
    。我有一个模型表示数据库中的数据,还有许多viewModels表示我想在
    ASP.NET MVC 5
    应用程序中发送到
    View
    的数据。@Raphael:我不认为那是地狱。在启动时定义映射的问题是,此时您需要同时了解表示/业务对象和DTO。将DTO隐藏在DAL中,然后映射到DAL未知的通用对象
    T
    ,这是有效的。
        var userRepo = new CrudRepo();
    
        var users = userRepo.GetData<UserViewModel>();
        var address = addressRepo.GetData<AddressViewModel>();