C#如何为ViewModel增加价值

C#如何为ViewModel增加价值,c#,sql-server,asp.net-mvc,database,C#,Sql Server,Asp.net Mvc,Database,我将尝试解释我正在尝试做的事情——目前,我使用的每个表都有一个模型,而ViewModel只包含表内容的一部分 我还向ModelView添加了一个或两个来自另一个表的额外属性。我的问题是,如何为viewModel对象指定值(我有一个函数可以为我提供该属性) ViewModel: public class StreetViewModel { public Int64 Id { get; set; } public Int64 CityId { get; set; } publ

我将尝试解释我正在尝试做的事情——目前,我使用的每个表都有一个模型,而ViewModel只包含表内容的一部分

我还向ModelView添加了一个或两个来自另一个表的额外属性。我的问题是,如何为viewModel对象指定值(我有一个函数可以为我提供该属性)

ViewModel:

public class StreetViewModel
{
    public Int64 Id { get; set; }
    public Int64 CityId { get; set; }
    public string Name { get; set; }
    public string CityName { get; set; } // THIS IS THE EXTRA PROPERTY
}
我的控制器分配对象的操作:

public IActionResult GetStreetByName(string streetName)
{
        var results = _repository.GetStreetByName(streetName); //Return a list of object of type Street
        return Ok(Mapper.Map<IEnumerable<StreetViewModel>>(results)); // convert Street object to STREETVIEWMODEL object and return it.
}
此方法将为我返回一个对象类型列表
Street
,在我拥有的每个
CityId
中,我还想选择
CityName
,它只出现在
City
表中

我还有一个通过ID获取城市对象的方法:

public City GetCityNameById(int cityId)
{
    return _context.City.Where(t => t.Id == cityId).FirstOrDefault();
}

我在哪里以及如何为
Street
的每个记录分配cityName?

如果您使用的是
自动映射器
,根据此工具的本机约定,您可以使用
tDestination
上的属性名称对属性进行命名,作为示例。让我们假设您拥有以下实体:

public class City
{
   public string Name { get; set; }
}

public class Street 
{
   public City City { get; set; }
}
然后,当您在
StreetViewModel
上定义名为
CityName
的属性时,自动映射程序将在
TSource
上查找名为
CityName
的属性,但找不到该属性。然后,它将尝试查看
City
,并在名为
Name
的属性之后找到它。这是autoMapper使用属性名称上字母的大小写进行的转换,因此,请注意它

自动映射-自定义映射 另一方面,您可以在映射上配置它。对于示例:

config.CreateMap<Street, StreetViewModel>()
   .ForMember(t => t.CityName, opt => opt.MapFrom(x => x.City.Name));
config.CreateMap()
.ForMember(t=>t.CityName,opt=>opt.MapFrom(x=>x.City.Name));
重要信息-选择N+1问题
当您使用
ORM
(实体框架或NHibernate)在数据库上进行查询时,请记住获取
City
属性,以避免延迟加载。如果在
街道
结果集中有许多记录,则会导致。使用
实体框架
可以使用,并且在
NHibernate
中可以使用。

如果使用
自动映射
,根据此工具的本机约定,您可以使用
tDestination
上的属性名称对属性进行nagivate,作为示例。让我们假设您拥有以下实体:

public class City
{
   public string Name { get; set; }
}

public class Street 
{
   public City City { get; set; }
}
然后,当您在
StreetViewModel
上定义名为
CityName
的属性时,自动映射程序将在
TSource
上查找名为
CityName
的属性,但找不到该属性。然后,它将尝试查看
City
,并在名为
Name
的属性之后找到它。这是autoMapper使用属性名称上字母的大小写进行的转换,因此,请注意它

自动映射-自定义映射 另一方面,您可以在映射上配置它。对于示例:

config.CreateMap<Street, StreetViewModel>()
   .ForMember(t => t.CityName, opt => opt.MapFrom(x => x.City.Name));
config.CreateMap()
.ForMember(t=>t.CityName,opt=>opt.MapFrom(x=>x.City.Name));
重要信息-选择N+1问题
当您使用
ORM
(实体框架或NHibernate)在数据库上进行查询时,请记住获取
City
属性,以避免延迟加载。如果在
街道
结果集中有许多记录,则会导致。使用
实体框架
可以使用,在
NHibernate
中可以使用。

您使用的是AutoMapper吗?是的,我是@FelipeOriani您应该使用ProjectTo,而不是Map。你在用AutoMapper吗?是的,我是@FelipeOriani你应该用ProjectTo,而不是Map。.Question-My
GetStreetByName
方法是选择街道列表。自动映射程序是否会通过
CityId
自动将它们分别附加到正确的城市?或者这个附件是如何发生的(我的DB有关系,但我的项目没有,我只是基于我的DB创建了类,而不是从另一个DB创建它们)。还有,我不明白你说的“把城市带回来…”是什么意思,确切地说是什么意思?我对.net和c相当陌生,对于初学者的问题非常抱歉。蚀刻城市意味着当ORM工具点击数据库上的查询时,它将生成一个连接,在街道的同一查询中从城市获取数据。如果不这样做,它将执行延迟加载来获取城市名称。好的,那么,我如何使用实体框架来建立这种关系呢?正如我所说,我从头开始在VS中创建了它们,尽管它们已经存在于DB中。那么我在哪里指定关系呢
city.id->street.cityId
问题-我的
GetStreetByName
方法是选择街道列表。自动映射程序是否会通过
CityId
自动将它们分别附加到正确的城市?或者这个附件是如何发生的(我的DB有关系,但我的项目没有,我只是基于我的DB创建了类,而不是从另一个DB创建它们)。还有,我不明白你说的“把城市带回来…”是什么意思,确切地说是什么意思?我对.net和c相当陌生,对于初学者的问题非常抱歉。蚀刻城市意味着当ORM工具点击数据库上的查询时,它将生成一个连接,在街道的同一查询中从城市获取数据。如果不这样做,它将执行延迟加载来获取城市名称。好的,那么,我如何使用实体框架来建立这种关系呢?正如我所说,我从头开始在VS中创建了它们,尽管它们已经存在于DB中。那么我在哪里指定关系呢<代码>city.id->street.cityId