NopCommerce 3.4省市联动

做法有两种,一种是在StateProvince表里面加个字段,另一种是新建两个表,用来存市、县的数据,表结构完全按照StateProvince走就好了。我这里用的是第二种做法,菜鸟一枚,代码写的比较烂,哪里写的不好欢迎提出来以便我提高自己。

第一步:去数据库,新建两个表,表我就不给了,直接给对应的Model

 1 using System.Collections.Generic;
 2 using Nop.Core.Domain.Localization;
 3 
 4 namespace Nop.Core.Domain.Directory
 5 {
 6     /// <summary>
 7     /// Represents a state/province
 8     /// </summary>
 9     public partial class City : BaseEntity, ILocalizedEntity
10     {
11         private ICollection<County> _counties;
12         /// <summary>
13         /// Gets or sets the country identifier
14         /// </summary>
15         public int StateProvinceId { get; set; }
16 
17         /// <summary>
18         /// Gets or sets the name
19         /// </summary>
20         public string Name { get; set; }
21 
22         /// <summary>
23         /// Gets or sets the abbreviation
24         /// </summary>
25         public string Abbreviation { get; set; }
26 
27         /// <summary>
28         /// Gets or sets a value indicating whether the entity is published
29         /// </summary>
30         public bool Published { get; set; }
31 
32         /// <summary>
33         /// Gets or sets the display order
34         /// </summary>
35         public int DisplayOrder { get; set; }
36 
37         /// <summary>
38         /// Gets or sets the country
39         /// </summary>
40         public virtual StateProvince StateProvince { get; set; }
41         public virtual ICollection<County> Countys
42         {
43             get { return _counties ?? (_counties = new List<County>()); }
44             protected set { _counties = value; }
45         }
46     }
47 
48 }
City.cs
 1 using Nop.Core.Domain.Localization;
 2 
 3 namespace Nop.Core.Domain.Directory
 4 {
 5     /// <summary>
 6     /// Represents a state/province
 7     /// </summary>
 8     public partial class County : BaseEntity, ILocalizedEntity
 9     {
10         /// <summary>
11         /// Gets or sets the country identifier
12         /// </summary>
13         public int CityId { get; set; }
14 
15         /// <summary>
16         /// Gets or sets the name
17         /// </summary>
18         public string Name { get; set; }
19 
20         /// <summary>
21         /// Gets or sets the abbreviation
22         /// </summary>
23         public string Abbreviation { get; set; }
24 
25         /// <summary>
26         /// Gets or sets a value indicating whether the entity is published
27         /// </summary>
28         public bool Published { get; set; }
29 
30         /// <summary>
31         /// Gets or sets the display order
32         /// </summary>
33         public int DisplayOrder { get; set; }
34 
35         /// <summary>
36         /// Gets or sets the country
37         /// </summary>
38         public virtual City City { get; set; }
39     }
40 
41 }
County.cs

当然,还需要修改StateProvince的Model

 1 using System.Collections.Generic;
 2 using Nop.Core.Domain.Localization;
 3 
 4 namespace Nop.Core.Domain.Directory
 5 {
 6     /// <summary>
 7     /// Represents a state/province
 8     /// </summary>
 9     public partial class StateProvince : BaseEntity, ILocalizedEntity
10     {
11         private ICollection<City> _cities;
12         /// <summary>
13         /// Gets or sets the country identifier
14         /// </summary>
15         public int CountryId { get; set; }
16 
17         /// <summary>
18         /// Gets or sets the name
19         /// </summary>
20         public string Name { get; set; }
21 
22         /// <summary>
23         /// Gets or sets the abbreviation
24         /// </summary>
25         public string Abbreviation { get; set; }
26 
27         /// <summary>
28         /// Gets or sets a value indicating whether the entity is published
29         /// </summary>
30         public bool Published { get; set; }
31 
32         /// <summary>
33         /// Gets or sets the display order
34         /// </summary>
35         public int DisplayOrder { get; set; }
36 
37         /// <summary>
38         /// Gets or sets the country
39         /// </summary>
40         public virtual Country Country { get; set; }
41         public virtual ICollection<City> Citys
42         {
43             get { return _cities ?? (_cities = new List<City>()); }
44             protected set { _cities = value; }
45         }
46     }
47 
48 }
StateProvince.cs

第二步:去Service层去做Crud,县、市的基本是一样的,我就只列出来一个。另外一个照着写就完了。

先定义接口:

 1 using System.Collections.Generic;
 2 using Nop.Core.Domain.Directory;
 3 
 4 namespace Nop.Services.Directory
 5 {
 6     public interface ICityService
 7     {
 8         void DeleteCity(City city);
 9         City GetCityById(int cityId);
10         City GetByAbbreviation(string abbreviation);
11         IList<City> GetCityByStateProvinceId(int stateProvinceId, bool showHidden = false);
12         void InsertCity(City city);
13         void UpdateCity(City city);
14     }
15 }
ICityService.cs

去实现接口:

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using Nop.Core.Caching;
  5 using Nop.Core.Data;
  6 using Nop.Core.Domain.Directory;
  7 using Nop.Services.Events;
  8 
  9 namespace Nop.Services.Directory
 10 {
 11     public  partial class CityService:ICityService
 12     {
 13         #region Constants
 14 
 15         /// <summary>
 16         /// Key for caching
 17         /// </summary>
 18         /// <remarks>
 19         /// {1} : country ID
 20         /// </remarks>
 21         private const string CITYS_ALL_KEY = "Nop.city.all-{0}";
 22         /// <summary>
 23         /// Key pattern to clear cache
 24         /// </summary>
 25         private const string CITYS_PATTERN_KEY = "Nop.city.";
 26 
 27         #endregion
 28 
 29         #region Fields
 30 
 31         private readonly IRepository<City> _cityRepository;
 32         private readonly IEventPublisher _eventPublisher;
 33         private readonly ICacheManager _cacheManager;
 34 
 35         #endregion
 36 
 37         #region Ctor
 38 
 39         /// <summary>
 40         /// Ctor
 41         /// </summary>
 42         /// <param name="cacheManager">Cache manager</param>
 43         /// <param name="stateProvinceRepository">State/province repository</param>
 44         /// <param name="eventPublisher">Event published</param>
 45         public CityService(ICacheManager cacheManager,
 46             IRepository<City> cityRepository,
 47             IEventPublisher eventPublisher)
 48         {
 49             _cacheManager = cacheManager;
 50             _cityRepository = cityRepository;
 51             _eventPublisher = eventPublisher;
 52         }
 53 
 54         #endregion
 55         public void DeleteCity(City city)
 56         {
 57             if(city==null)
 58                 throw new ArgumentNullException("city");
 59             _cityRepository.Delete(city);
 60             _cacheManager.RemoveByPattern(CITYS_PATTERN_KEY);
 61             _eventPublisher.EntityDeleted(city);
 62         }
 63 
 64         public City GetCityById(int cityId)
 65         {
 66             if (cityId == 0)
 67             {
 68                 return null;
 69             }
 70             return _cityRepository.GetById(cityId);
 71         }
 72 
 73         public City GetByAbbreviation(string abbreviation)
 74         {
 75             var query = from sp in _cityRepository.Table
 76                 where sp.Abbreviation == abbreviation
 77                 select sp;
 78             var city = query.FirstOrDefault();
 79             return city;
 80         }
 81 
 82         public IList<City> GetCityByStateProvinceId(int stateProvinceId, bool showHidden = false)
 83         {
 84             string key = string.Format(CITYS_ALL_KEY, stateProvinceId);
 85             return _cacheManager.Get(key, () =>
 86             {
 87                 var query= from sp in _cityRepository.Table 
 88                                  orderby  sp.DisplayOrder
 89                            where sp.StateProvinceId == stateProvinceId &&
 90                        (showHidden || sp.Published)
 91                            select sp;
 92                 var city = query.ToList();
 93                 return city;
 94             });
 95         }
 96 
 97         public void InsertCity(City city)
 98         {
 99             if (city == null)
100                 throw new ArgumentNullException("city");
101 
102             _cityRepository.Insert(city);
103 
104             _cacheManager.RemoveByPattern(CITYS_PATTERN_KEY);
105 
106             //event notification
107             _eventPublisher.EntityInserted(city);
108         }
109 
110         public void UpdateCity(City city)
111         {
112             if (city == null)
113                 throw new ArgumentNullException("city");
114 
115             _cityRepository.Update(city);
116 
117             _cacheManager.RemoveByPattern(CITYS_PATTERN_KEY);
118 
119             //event notification
120             _eventPublisher.EntityUpdated(city);
121         }
122     }
123 }
CityService.cs

这是市的,县的照着这个写就完了。注意缓存那块也一定要给把那个Key给改了,不然会重名的。

第三步:去Nop.Web.Framework把刚写的这些Service注入。

1  builder.RegisterType<CityService>().As<ICityService>().SingleInstance();
2             builder.RegisterType<CountyService>().As<ICountyService>().SingleInstance();
DependencyRegistrar.cs

第三步:修改他转换po和vo的方法,我这个做的是国内的电子商务网站,所以,国家那里我直接就写死了,而且在后续的界面中,我也直接把国家给干掉了。

  1 public static void PrepareModel(this AddressModel model,
  2             Address address, bool excludeProperties, 
  3             AddressSettings addressSettings,
  4             ILocalizationService localizationService = null,
  5             IStateProvinceService stateProvinceService = null,
  6               #region yunchen.bai
  7          ICityService cityService=null,
  8             ICountyService countyService=null ,
  9     #endregion
 10             Func<IList<Country>> loadCountries = null,
 11             bool prePopulateWithCustomerFields = false,
 12             Customer customer = null
 13          
 14             )
 15         {
 16             if (model == null)
 17                 throw new ArgumentNullException("model");
 18 
 19             if (addressSettings == null)
 20                 throw new ArgumentNullException("addressSettings");
 21 
 22             if (!excludeProperties && address != null)
 23             {
 24                 model.Id = address.Id;
 25                 model.FirstName = address.FirstName;
 26                 model.LastName = address.LastName;
 27                 model.Email = address.Email;
 28                 model.Company = address.Company;
 29                 model.CountryId = address.CountryId;
 30                 model.CountryName = address.Country != null 
 31                     ? address.Country.GetLocalized(x => x.Name) 
 32                     : null;
 33                 model.StateProvinceId = address.StateProvinceId;
 34                 model.StateProvinceName = address.StateProvince != null 
 35                     ? address.StateProvince.GetLocalized(x => x.Name)
 36                     : null;
 37                 model.City = address.City;
 38                 model.Address1 = address.Address1;
 39                 model.Address2 = address.Address2;
 40                 model.ZipPostalCode = address.ZipPostalCode;
 41                 model.PhoneNumber = address.PhoneNumber;
 42                 model.FaxNumber = address.FaxNumber;
 43             }
 44 
 45             if (address == null && prePopulateWithCustomerFields)
 46             {
 47                 if (customer == null)
 48                     throw new Exception("Customer cannot be null when prepopulating an address");
 49                 model.Email = customer.Email;
 50                 model.FirstName = customer.GetAttribute<string>(SystemCustomerAttributeNames.FirstName);
 51                 model.LastName = customer.GetAttribute<string>(SystemCustomerAttributeNames.LastName);
 52                 model.Company = customer.GetAttribute<string>(SystemCustomerAttributeNames.Company);
 53                 model.Address1 = customer.GetAttribute<string>(SystemCustomerAttributeNames.StreetAddress);
 54                 model.Address2 = customer.GetAttribute<string>(SystemCustomerAttributeNames.StreetAddress2);
 55                 model.ZipPostalCode = customer.GetAttribute<string>(SystemCustomerAttributeNames.ZipPostalCode);
 56                 model.City = customer.GetAttribute<string>(SystemCustomerAttributeNames.City);
 57                 //ignore country and state for prepopulation. it can cause some issues when posting pack with errors, etc
 58                 //model.CountryId = customer.GetAttribute<int>(SystemCustomerAttributeNames.CountryId);
 59                 //model.StateProvinceId = customer.GetAttribute<int>(SystemCustomerAttributeNames.StateProvinceId);
 60                 model.PhoneNumber = customer.GetAttribute<string>(SystemCustomerAttributeNames.Phone);
 61                 model.FaxNumber = customer.GetAttribute<string>(SystemCustomerAttributeNames.Fax);
 62             }
 63 
 64             //countries and states
 65             if (addressSettings.CountryEnabled && loadCountries != null)
 66             {
 67                 if (localizationService == null)
 68                     throw new ArgumentNullException("localizationService");
 69 
 70                 model.AvailableCountries.Add(new SelectListItem() { Text = localizationService.GetResource("Address.SelectCountry"), Value = "0" });
 71                 foreach (var c in loadCountries())
 72                 {
 73                     model.AvailableCountries.Add(new SelectListItem()
 74                     {
 75                         Text = c.GetLocalized(x => x.Name),
 76                         Value = c.Id.ToString(),
 77                         Selected = c.Id == model.CountryId
 78                     });
 79                 }
 80                 model.CountryId = 21;
 81                 if (address != null)
 82                 {
 83                     model.CountyId = address.CountyId;
 84                     model.CityId = address.CityId;
 85                 }
 86                 if (addressSettings.StateProvinceEnabled)
 87                 {
 88                     //states
 89                     if (stateProvinceService == null)
 90                         throw new ArgumentNullException("stateProvinceService");
 91 
 92                     var states = stateProvinceService
 93                         .GetStateProvincesByCountryId(21)//这块直接给写死成中国
 94                         .ToList();
 95                     if (states.Count > 0)
 96                     {
 97                         foreach (var s in states)
 98                         {
 99                             model.AvailableStates.Add(new SelectListItem()
100                             {
101                                 Text = s.GetLocalized(x => x.Name),
102                                 Value = s.Id.ToString(), 
103                                 Selected = (s.Id == model.StateProvinceId)
104                             });
105                         }
106                     }
107                     else
108                     {
109                         model.AvailableStates.Add(new SelectListItem()
110                         {
111                             Text = localizationService.GetResource("Address.OtherNonUS"),
112                             Value = "0"
113                         });
114                     }
115                     #region yunchen.bai 2014.10.27
116                     if (cityService == null)
117                         throw new ArgumentNullException("cityService");
118                     var firstProvince = stateProvinceService.GetStateProvincesByCountryId(21).FirstOrDefault() ??
119                                         new StateProvince();
120                     var citys =
121                         cityService.GetCityByStateProvinceId(model.StateProvinceId != null
122                             ? model.StateProvinceId.Value
123                             : firstProvince.Id).ToList();
124                     var firstCity = cityService.GetCityByStateProvinceId(firstProvince.Id).FirstOrDefault() ??
125                                      new City();
126                     if (citys.Count > 0)
127                     {
128                         foreach (var c in citys)
129                         {
130                            model.AvailableCity.Add(new SelectListItem()
131                            {
132                                Text = c.GetLocalized(x=>x.Name),
133                                Value = c.Id.ToString(),
134                                Selected = (c.Id==model.CityId)
135                            });
136                         }
137                     }
138                     else
139                     {
140                         model.AvailableCity.Add(new SelectListItem()
141                         {
142                             Text = localizationService.GetResource("Address.OtherNonUS"),
143                             Value = "0"
144                         });
145                     }
146                     if(countyService==null)
147                         throw  new ArgumentNullException("countyService");
148                     var counties = countyService.GetCountyByCityId(model.CityId.HasValue?model.CityId.Value:firstCity.Id);
149                     if (counties.Count > 0)
150                     {
151                         foreach (var county in counties)
152                         {
153                             model.AvailableCounty.Add(new SelectListItem()
154                             {
155                                 Text = county.GetLocalized(x=>x.Name),
156                                 Value = county.Id.ToString(),
157                                 Selected = (county.Id==model.CityId)
158                             });
159                         }
160                     }
161                     else
162                     {
163                         model.AvailableCity.Add(new SelectListItem()
164                         {
165                             Text = localizationService.GetResource("Address.OtherNonUS"),
166                             Value = "0"
167                         });
168                     }
169 
170                     #endregion
171 
172 
173                 }
174             }
MappingExtensions.cs

未完待续.....

原文地址:https://www.cnblogs.com/baiyunchen/p/4066978.html