来自数据库的codefirst 怎么用
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了来自数据库的codefirst 怎么用相关的知识,希望对你有一定的参考价值。
如果你还在为支持xxx上下文的模型已在数据库创建后发生更改。请考虑使用 Code First 迁移更新数据库
找到你的数据库上下文所在的类库(一般都是写在项目中的model中,也有的独立model类库)
打开Nuget 程序包管理控制台
输入:Enable-Migrations 回车
如果正确的话 则显示已为项目 xxx启用 Code First 迁移。
我在这里说下 几种有可能出现的错误:
1.No context type was found in the assembly xxx
在当前项目中 没有找到数据库上下文,也就是DbContext 继承的的 "数据库.cs"
2.The EntityFramework package is not installed on project xxx
当前项目已经找到了数据上下文,但是没有EntityFrameWork 需要安装输入 install-package entityframework(手大的 不知道对不对)
基本就这两个问题,如果安装成功则在项目中 出现Migrations文件夹,里面会记录每次数据迁移所发生的变化。
非常好用,不用再删除数据库 重新生成 数据丢失等问题。
常用语句 :enable-Migrations -Force 替换迁移数据文件 update-database 更新 add-migration 添加新的更新文件
求采纳为满意回答 参考技术A 如果你还在为
支持xxx上下文的模型已在数据库创建后发生更改。请考虑使用 Code First 迁移更新数据库
找到你的数据库上下文所在的类库(一般都是写在项目中的model中,也有的独立model类库)
打开Nuget 程序包管理控制台
输入:Enable-Migrations 回车
如果正确的话 则显示已为项目 xxx启用 Code First 迁移。
我在这里说下 几种有可能出现的错误:
1.No context type was found in the assembly xxx
在当前项目中 没有找到数据库上下文,也就是DbContext 继承的的 "数据库.cs"
2.The EntityFramework package is not installed on project xxx
当前项目已经找到了数据上下文,但是没有EntityFrameWork 需要安装输入 install-package entityframework(手大的 不知道对不对)
基本就这两个问题,如果安装成功则在项目中 出现Migrations文件夹,里面会记录每次数据迁移所发生的变化。
非常好用,不用再删除数据库 重新生成 数据丢失等问题。
常用语句 :enable-Migrations -Force 替换迁移数据文件 update-database 更新 add-migration 添加新的更新文件。
我们是怎么实现Grpc CodeFirst
前言:
Grpc默认是ProtoFirst的,即先写 proto文件,再生成代码,需要人工维护proto,生成的代码也不友好,所以出现了Grpc CodeFirst,下面来说说我们是怎么实现Grpc CodeFirst
目录:
实现和WCF一样的CodeFirst
(1). 实现Grpc CodeFirst, 简化WCF一定要抽取接口的问题
(2). 通过代码生成proto和注释,给第三方语言使用
(3). 实现Grpc DashBoard,用于Http远程调用和管理
(4). 实现服务注册与发现
(5). 实现分布式日志跟踪
(6). 日志监控等等
我们是怎么实现Grpc CodeFirst
1.要实现CodeFirst先要了解ProtoFirst生成的代码,下面我截了部分生成代码
(1).关键是这个BindService,用于把实现的Grpc方法绑定到GrpcServiceDefinition
public static partial class Greeter { static readonly string __ServiceName = "helloworld.Greeter"; static readonly grpc::Marshaller<global::Helloworld.HelloRequest> __Marshaller_helloworld_HelloRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloRequest.Parser.ParseFrom); static readonly grpc::Marshaller<global::Helloworld.HelloReply> __Marshaller_helloworld_HelloReply = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloReply.Parser.ParseFrom); static readonly grpc::Method<global::Helloworld.HelloRequest, global::Helloworld.HelloReply> __Method_SayHello = new grpc::Method<global::Helloworld.HelloRequest, global::Helloworld.HelloReply>( grpc::MethodType.Unary, __ServiceName, "SayHello", __Marshaller_helloworld_HelloRequest, __Marshaller_helloworld_HelloReply); static readonly grpc::Method<global::Helloworld.HelloRequest, global::Helloworld.HelloReply> __Method_SayHelloStream = new grpc::Method<global::Helloworld.HelloRequest, global::Helloworld.HelloReply>( grpc::MethodType.ClientStreaming, __ServiceName, "SayHelloStream", __Marshaller_helloworld_HelloRequest, __Marshaller_helloworld_HelloReply); /// <summary>Creates service definition that can be registered with a server</summary> /// <param name="serviceImpl">An object implementing the server-side handling logic.</param> public static grpc::ServerServiceDefinition BindService(GreeterBase serviceImpl) { return grpc::ServerServiceDefinition.CreateBuilder() .AddMethod(__Method_SayHello, serviceImpl.SayHello) .AddMethod(__Method_SayHelloStream, serviceImpl.SayHelloStream).Build(); } /// <summary>Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. /// Note: this method is part of an experimental API that can change or be removed without any prior notice.</summary> /// <param name="serviceBinder">Service methods will be bound by calling <c>AddMethod</c> on this object.</param> /// <param name="serviceImpl">An object implementing the server-side handling logic.</param> public static void BindService(grpc::ServiceBinderBase serviceBinder, GreeterBase serviceImpl) { serviceBinder.AddMethod(__Method_SayHello, serviceImpl == null ? null : new grpc::UnaryServerMethod<global::Helloworld.HelloRequest, global::Helloworld.HelloReply>(serviceImpl.SayHello)); serviceBinder.AddMethod(__Method_SayHelloStream, serviceImpl == null ? null : new grpc::ClientStreamingServerMethod<global::Helloworld.HelloRequest, global::Helloworld.HelloReply>(serviceImpl.SayHelloStream)); } }
(2).__Marshaller_helloworld_HelloRequest这个是实现protobuffer的序列化和反序列化的一个委托
服务的请求参数和返回参数,我们使用Protobuf-net来实现序列化和反序列化,和 WCF一样需要给类打上标签
/// <summary> /// 加法请求参数 /// </summary> [ProtoContract] public class AddRequest { /// <summary> /// 第一个数字 /// </summary> [ProtoMember(1)] public int Num1 { get; set; } /// <summary> /// 第二个数字 /// </summary> [ProtoMember(2)] public int Num2 { get; set; } }
2.要实现CodeFirst需要实现这个BindService,把我们的Grpc方法添加到ServerServiceDefinition
(1).我们让Grpc服务实现IGrpcService空接口,用于标识是GrpcService
/// <summary> /// MathGrpc /// </summary> public class MathGrpc : IGrpcService { /// <summary> /// 加法 /// </summary> /// <param name="request"></param> /// <param name="context"></param> /// <returns></returns> public Task<IntMessage> Add(AddRequest request, ServerCallContext context) { var result = new IntMessage(); result.Value = request.Num1 + request.Num2; return Task.FromResult(result); } }
(2).获取实现了IGrpcService接口的类,然后反射获取方法,再添加到ServerServiceDefinition即可
/// <summary> /// 注入IGrpcService /// </summary> /// <param name="grpcServices"></param> /// <returns></returns> private ServerBuilder UseGrpcService(IEnumerable<IGrpcService> grpcServices) { var builder = ServerServiceDefinition.CreateBuilder(); grpcServices.ToList().ForEach(grpc => GrpcMethodHelper.AutoRegisterMethod(grpc, builder)); _serviceDefinitions.Add(builder.Build()); return this; }
未完,待续,欢迎评论拍砖
这些功能早在2018年就已经实现并运行在生产,感兴趣的同学可以去 github上查看,你要的都有,欢迎提issue
以上是关于来自数据库的codefirst 怎么用的主要内容,如果未能解决你的问题,请参考以下文章