.net Core 踩坑记:全新零框架项目搭建

参考【ASP.NET Core跨平台开发从入门到实战 [张剑桥].pdf】从零搭建.net core项目(名称叫NetNote),又踩了不少坑,趁着有印象记下:

1、选用的是最简单最空的项目,说是WebApplication,实际和控制台一样了,只有最基本的Starup.cs、Program.cs,以及几个json,其它全没有。这种最好,一个个往上搭,看需要什么东西

 

2、看有些core源码没有再分一层数据层出来,直接在控制器搞定。我还是按习惯把默认的改为NetNote.UI,再建一个类库,叫NetNote.DAL

一下没注意,选类库的时候,还是选了上面的.net Standard,结果代码都写好了,发现是不能CodeFirst还是什么的,总之提示不是core项目,报错。仔细一看,原来新建项目时下面还有专门的.net core 类库。

再建个core类库,把代码剪切过来,把旧的删了,再改文件夹名称、改解决方案里文件夹名称,正常了

 

3、照着教程先来DAL层,要装Framework.Core.SQLServer、Framework.Core.Tools,很久之前(去年?前年?)还听说ef core支持不好,现在应该很成熟了

 

4、照着把DAL层的实体类、接口、接口实现仓储建好,要在UI层配置,教程里都建了接口,平时工作都没先定义接口再做增删改查,导致叫法不统一,比如有的叫Update,有的叫Save,但也不是很影响就是了,都有代码提示。

 

5、坑都在这里踩了,重点说一下

public void ConfigureServices(IServiceCollection services)
        {
            string connection = @"Server=.;Database=Note;UID=sa;PWD=XXX;";
            services.AddDbContext<NoteContext>(options => options.UseSqlServer(connection));
            services.AddScoped<INoteRepository, NoteRepository>();
            services.AddMvc();
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            //app.Run(async (context) =>
            //{
            //    await context.Response.WriteAsync("Hello World!");
            //});

            app.UseMvcWithDefaultRoute();
        }

  仓储层建好后要在ConfigureServices配置

  一开始MVC不识别,即浏览器访问不了(因为是完全空的项目),要配置services.AddMvc(),并在Configure里配置默认路由。这个弄了半天,以为都底层默认支持原始路由。

  MVC配置后仍无法用,所有页面均为Hello World,原来是初始代码里有这么一句(上面注释了的),所有输出均为Hello World了

 

6、好不容易UI层弄好了,要CodeFirst生成数据库,死活不行,一开始说要装Core Tools,还有个什么东西忘了,因为我是空项目一个个往里装所需插件的。装完后还是不行,最后用Package Manager又可以了

 

 

 

会多一个这样的文件夹出来,查网上资料好像也是说如果要直接用dotnet ef迁移,要提前把这个迁移文件夹及内容配好。用PM的会帮我们配

平时都是DBFirst,没用过CodeFirst,刚好尝试下

 

 

 7、整体项目文件夹如下:

 

教程是另弄了个ViewModel来和实体对应,JAVA也基本是这样,在数据库实体之外再弄一个VO来对应。我一直觉得很麻烦、没必要。

如果字段有所不同还好,如果是完全一样的,何必这样再来一遍?退一步说真要这样弄个实体,好歹也用反射什么的自动赋值吧

这个之前有和水平较高的大佬讨论过,也网上看过,说是为了不暴露数据库内部结构,那如果不想暴露,好歹ViewModel要取完全不同的才有意义吧,而且数据库字段名给别人知道了也没什么特别要紧。

还有种说法是为了不因数据库结构而改变前端什么的,也不对啊,数据库如果变了,前端模型也得跟着变,代码也得跟着变,都是要一条龙的

这个可能就和先接口再实现一样吧,是一种规范,大项目要这样约束好,平时小项目感觉是不要紧,既不要接口,也不要对应UI实体类,节省时间,也不会带来什么后遗症

 

 8、顺便说下,core都是用这种异步写法了,虽说小项目也是效率看不出来,但养成习惯就好,毕竟是底层更高效的,写了也不吃亏

主要是方法上用asyn Task,内部代码用await,其它没什么区别

public async Task<IActionResult> Index()
        {
            List<Note> notes = await noteRepository.ListAsync();
            return View(notes);
        }

 

9、控制器上都这样用注入了,原先公司用的是在Base里用单例工厂,感觉是一样用,就是不用实例化就能调后台呗,不是一回事?

private INoteRepository noteRepository;
        public NoteController(INoteRepository diNoteRepository)
        {
            noteRepository = diNoteRepository;
        }

 

公司目前是这样,单例的工厂提前备好服务,哪里要用直接用就可以,也是无需再实例化,这个单例和注入的区别,还要再研究下基础知识才行

 public class BaseController : Controller
    {protected EntityRepositoryService ucEntity = UserCenterFactory.EntityRepositoryService;
        protected SqlRepositoryService ucSql = UserCenterFactory.SqlRepositoryService;

 =================

10、TagHelpers的坑。。。照着教程用 <a asp-action="Add">添加Note</a> ,但解析出来,居然就是原原本本的 <a asp-action="Add">添加Note</a> 这种html,为什么不翻译成a标签的href之类的呢?

找了半天,原来还是因为新建的是空项目的原因,默认会自带个_ViewImports.cshtml,里面就一句话

@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

手动在视图页面上面加了这个就好了

11、还有个坑,教程上漏写了一个普通视图的控制器入口,我还以为框架底层又有什么新写法,直接兼容页面和提交呢(或还是我哪里没配对?)

    public IActionResult Add()
        {
            return View();
        }

        [HttpPost]
        public async Task<IActionResult> Add(NoteModel nmModel)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            await noteRepository.AddAsync(new Note
            {
                Title = nmModel.Title,
                Content = nmModel.Content,
                Create = DateTime.Now
            });
            return RedirectToAction("Index");
        }

教程里面是没有上面普通的public IActionResult Add(){return View()} 的,只有下面post的保存方法,我就看了半天,那Add页面是怎么展示的呢?原先只有接收post啊。

也不知是真支持这样写,但需要另外配(或框架哪里有处理),还是真漏了,反正我加上普通的方法让它返回到页面就可以了

 

12、外键

平时EF从没用过外键,不方便,网上也建议不要用外键,数据库只做好存储的事,不要搭上业务。

教程里这样写,试了会报错,建表是会自动建外键,但新增时,只增了一张表,另张表没处理,是外键会自动处理?感觉是需要手动加一句吧,两张表都要保存,不然外键的那张表怎么知道要存什么数据。

去掉了外键,单表保存正常,这本教程感觉源码直接拿来上机会有些问题,刚好在排查问题时能加深理解

posted @ 2019-05-26 10:47  文刂亻右景彡  阅读(718)  评论(3编辑  收藏  举报