周一正式开始了毕业工作。然后学习调试了近4天,刚刚总算在同事的帮助下做出了一个基于Asp.Net MVC4的Hello World显示。
这是一篇最为基础的记录教程,记录内容可能有点混乱,旨在能在刚调试完成,趁着印象深刻急速记录,晚些会重新做一遍这个项目写一个更为详细的博文。
下面是正文:
整个网站项目由若干个功能子项目组成。而我要做的是自己做一个口香糖demo混在原项目中。所以基础的配置我就先不说了。首先复制别的子项目一份并且重命名为Aibol.Sugar,并且导入visual studio。导入后的项目如下图所示。
然后把多余的文件删除,然后写相应的代码。最后截图如下。
好了,上面就是完成效果,教程结束。
开个玩笑。
下面是核心步骤:
1.创建数据库jiedian.Aibol.Sugar。
注意,ID一定要是uniqueidentifier类型!敲黑板!因为后面是要继承父类进行操作,所以就限定死了ID必须是该类型。
另外一定要有一个Status状态,这个我忘记为什么了,但是一定要加(也有可能是我记错了,我会在下个教程中说明的,应该)
2.在项目的Repositories文件夹中创建SqlServer文件夹和一个ISugarRepository接口。然后在SqlServer中创建SugarRepository和数据库访问模板Sugar.dbml。如下图所示。
为什么是这种格式呢?扔粉笔!很重要啊!如果后期需要实现mysql数据库,那么只要在Repositories文件夹中再创建一个“mysql”文件夹,接口都共用ISugarRepository接口。也就是说用同一套接口实现不同的数据库。
3.Sugar.dbml是这样创建的:新建一个“LINQ to SQL Classes”,即可创建一个空dbml文件。在这里重命名为Sugar.dbml。然后在SQL Server Object Explorer窗口中,把jiedian.Aibol.Sugar数据库直接拖到这个空dbml文件中,就可以成功创建一个非空的dbml文件。
题外话:这个东西到底有什么用我也不是很清楚,反正这么用就对了。表示从Java的SSM框架转到Asp.Net MVC4还是有点水土不服的。
4.然后ISugarRepository.cs的内容改成这样:
namespace Aibol.Modules.Sugars.Repositories { public interface ISugarRepository : IRepositoryBase<Sugars.Models.Sugar> { } }
我也不知道为什么,照着写就对了。
5.相对应的SugarRepository.cs改成这样:
namespace Aibol.Modules.Sugars.Repositories.SqlServer { public class SugarRepository : ISugarRepository { private readonly SugarDataContext _context; public SugarRepository(SugarDataContext context) { _context = context; } public int Delete(SearchCriteria searchCriteria) { throw new NotImplementedException(); } public IQueryable<Models.Sugar> GetCollection(SearchCriteria searchCriteria) { var sugarFilter = FilterSugar(searchCriteria); return _context .jiedian_Aibol_Sugars .Where(sugarFilter) .OrderByDescending(r => r.CreatedWhen) .Select(t => t.MapToEntity<Models.Sugar>()); } private Expression<Func<jiedian_Aibol_Sugar, bool>> FilterSugar(SearchCriteria sc) { var predicate = PredicateBuilder.True<jiedian_Aibol_Sugar>(); if (sc.ContainsKey("name")) { predicate = predicate.And(t => t.Name.IndexOf(sc["name"], StringComparison.Ordinal) > -1); } if (sc.ContainsKey("term")) { var term = sc["term"].Trim(); predicate = predicate.And(p => p.Name.IndexOf(term) > -1 ); } return predicate; } //获取实例 public Models.Sugar GetInstance(Guid id) { return _context .jiedian_Aibol_Sugars .Where(t => t.ID == id) .Select(t => t.MapToEntity<Models.Sugar>()) .FirstOrDefault(); } //保存 public Models.Sugar Save(Models.Sugar item) { jiedian_Aibol_Sugar aibolSugar = null; if(item.ID!=Guid.Empty) { aibolSugar = _context.jiedian_Aibol_Sugars.FirstOrDefault(t => t.ID == item.ID); } if (aibolSugar == null) { item.ID = Guid.NewGuid(); aibolSugar = new jiedian_Aibol_Sugar(); _context.jiedian_Aibol_Sugars.InsertOnSubmit(aibolSugar); } item.MergeToDbModel(aibolSugar); _context.SubmitChanges(); return item; } //修改 public int UpdateStatus(SearchCriteria searchCriteria) { var ids = searchCriteria["ids"].Split(‘,‘).Select(Guid.Parse); var list = _context.jiedian_Aibol_Sugars.Where(t => ids.Contains(t.ID)).ToList(); var count = 0; foreach (var item in list) { switch (searchCriteria.Status) { case 4: count++; break; case 8: count++; break; } } _context.SubmitChanges(); return count; } } }
同理,原理不知。
6.Services文件夹下创建service文件,其中包括ISugarService和SugarService。
其中ISugarService文件内容如下:
namespace Aibol.Modules.Sugars.Services { public interface ISugarService : IServiceBase<Models.Sugar> { object GetInstance(object iD); } }
SugarService文件内容如下:
namespace Aibol.Modules.Sugars.Services { class SugarService:ISugarService { private readonly ISugarRepository _sugarRepository; private readonly IAibolCacheModule _cache; private readonly ITenantService _tenantService; public SugarService(ISugarRepository sugarRepository, IBackgroundServiceRegistry backgroundService, IAibolCacheModule cache, ITenantService tenantService) { _sugarRepository = sugarRepository; _cache = cache; _tenantService = tenantService; } public Models.Sugar GetInstance(Guid id) { if (id == Guid.Empty) return null; var sugar = _cache.GetItem(id.ToString(), () => { var s = _sugarRepository.GetInstance(id); return s; }, null); return sugar; } public Models.Sugar Save(Models.Sugar item) { if (!string.IsNullOrEmpty(item.Name) && string.IsNullOrEmpty(item.SpellChar)) { item.SpellChar = item.Name.GetSpellCode(); } _sugarRepository.Save(item); _cache.Invalidate(item.GetCacheItemKey()); return GetInstance(item.ID); } public IPageOfItems<Models.Sugar> GetCollection(SearchCriteria searchCriteria) { var list = _sugarRepository .GetCollection(searchCriteria) .GetPage(searchCriteria.PageIndex, searchCriteria.PageSize); foreach (var item in list) { FillDependencies(item); } return list; } private void FillDependencies(Models.Sugar u) { if (u.CreatedBy != null) { u.CreatedBy = u.CreatedBy.ID == u.ID ? u : GetInstance(u.CreatedBy.ID); } if (u.LastModifiedBy != null) { u.LastModifiedBy = u.LastModifiedBy.ID == u.ID ? u : GetInstance(u.LastModifiedBy.ID); } if (u.Tenant != null) { u.Tenant = _tenantService.GetInstance(u.Tenant.ID); } } public int UpdateStatus(SearchCriteria searchCriteria) { var count = _sugarRepository.UpdateStatus(searchCriteria); return count; } public int Delete(SearchCriteria searchCriteria) { throw new NotImplementedException(); } public object GetInstance(object iD) { throw new NotImplementedException(); } } }
7.然后创建controller。在Controllers文件夹下创建SugarController,内容如下:
namespace Aibol.Modules.Sugars.Controllers { [Application(Name = "Data.Sugar", DisplayOrder = 10)] public class SugarController:AibolController { //私有变量 private readonly IBackgroundServiceRegistry _backgroundServiceRegistry; private readonly ISugarService _sugarService; public SugarController(IValidationService validationService, AibolContext context, ISerializationService serializationService, IBackgroundServiceRegistry backgroundServiceRegistry, ISugarService sugarService) : base(validationService, context, serializationService) { _backgroundServiceRegistry = backgroundServiceRegistry; _sugarService = sugarService; } public SugarController(IValidationService validationService, AibolContext context, ISerializationService serializationService, ILogService logService, ILocalizationService localizationService, IBackgroundServiceRegistry backgroundServiceRegistry, ISugarService sugarService) : base(validationService, context, serializationService, logService, localizationService) { _backgroundServiceRegistry = backgroundServiceRegistry; _sugarService = sugarService; } internal object list(object p) { throw new NotImplementedException(); } [HttpGet] [AllowAnonymous] [ActionName("Sugars")] public object SugarIndex() { var model = new AibolViewModel { Container = new SugarsContainer() }; return model; } } }
除了路由那部分,其它内容都很迷,我表示看不大懂,好像是在注册一些东西?说到注册,请看8。
8.在项目根目录下创建SugarModule.cs,继续敲黑板!在这里坑了很久,必须要注册service和repository!
namespace Aibol.Modules.Sugars { class SugarModule: IAibolModule, IAibolDataProvider { private readonly IUnityContainer _container; public SugarModule(IUnityContainer container) { _container = container; } //fixed public void Initialize() { } //fixed public void Unload() { } //fixed public void RegisterRoutes(RouteCollection routes) { routes.MapRoute( "Sugars",//路由名称 "sugars",//带有参数的url new {Controller="Sugar",action="Sugars"},//指定控制器以及默认参数值 null ); } //fixed public void RegisterCatchAllRoutes(RouteCollection routes) { } //sth problems public void RegisterFilters(IFilterRegistry filterRegistry) { filterRegistry.Add(Enumerable.Empty<IFilterCriteria>(),typeof(SugarActionFilter)); var contentItemsInputCriteria=new ControllerActionFilterCriteria(); contentItemsInputCriteria.AddMethod<SugarController>(p=>p.list(null)); filterRegistry.Add(new[] {contentItemsInputCriteria},typeof(GridActionFilter)); } //fixed public void RegisterModelBinders(ModelBinderDictionary modelBinders) { } public void RegisterWithContainer() { //在这里注册Service _container .RegisterType<ISugarService, SugarService>(); } public void ConfigureProvider(AibolConfigurationSection config, AibolDataProviderConfigurationElement dataProviderConfig, IUnityContainer container) { var connStr = !string.IsNullOrEmpty(dataProviderConfig.ConnectionString) ? dataProviderConfig.ConnectionString : config.Providers.DefaultConnectionString; var connParam=new ResolvedParameter<string>(connStr); if (dataProviderConfig.Category == "LinqToSql") { //在这里注册Repository container.RegisterType<SugarDataContext>(new TransientLifetimeManager(), new InjectionConstructor(connParam)).RegisterType<ISugarRepository, SugarRepository>(); } } } }
9.在主项目目录Views下创建Sugar文件夹,在里面创建前端展示页面Sugars.cshtml。
10.在主项目config里分别在各个节点加入如下代码:
在dataProviders中加入如下内容:
<add name="Sugars" type="Aibol.Modules.Sugars.SugarModule, Aibol.Sugars" category="LinqToSql" />
在modules中加入如下内容:
<add name="Sugars" type="Aibol.Modules.Sugars.SugarModule, Aibol.Sugars" dataProvider="Sugars" />
11.运行项目,跑一把,下面是浏览截图。- -;
花了四天总算把一个Hello口香糖写出来。很感谢我同事啊,不厌其烦的教我??感觉自己蠢爆天??
一些相关的小知识:
Alt+Enter可以直接进行代码整理和提示。
在coding.net可以注册git账号然后同步项目代码。
在类名或者方法上按F12可以跳转到该类或者该方法的定义位置。
调试过程中,F10是该代码页面依次执行(不会进入方法进行细分调试)。F11是依次执行每一行代码(如果遇到方法,会进入该方法逐步调试)
Debug->Windows->Threads,可以在调试中对线程进行锁定等操作。
如果发现项目无法调试,很可能你的调试模式调成了Release,把它调整为Debug就可以了。