C#如何为ViewModel增加价值
我将尝试解释我正在尝试做的事情——目前,我使用的每个表都有一个模型,而ViewModel只包含表内容的一部分 我还向ModelView添加了一个或两个来自另一个表的额外属性。我的问题是,如何为viewModel对象指定值(我有一个函数可以为我提供该属性) 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
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-MyGetStreetByName
方法是选择街道列表。自动映射程序是否会通过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