• .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从没用过外键,不方便,网上也建议不要用外键,数据库只做好存储的事,不要搭上业务。

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

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

  • 相关阅读:
    经典小程序源码及其下载地址
    基于cropper.js的图片上传和裁剪
    【组件】微信小程序input搜索框的实现
    如何打造个人技术影响力
    一位90后程序员的自述:如何从年薪3w到30w!
    状态模式(State)(开关灯,状态实例为类,不同状态,不同行为)
    责任链模式(Chain of Responsibility、Handler)(请求处理建立链)
    java中创建对象的五种方法
    PrintWrite
    观察者模式(Observer、Subject、ConcreteSubject、ConcreteObserver)(监护、订阅)
  • 原文地址:https://www.cnblogs.com/liuyouying/p/10925353.html
Copyright © 2020-2023  润新知