private CProtoRpc BuildRpcFromStoredProc(CProtoFile protoFile, CProtoService protoService, CMethod method, CStoredProcedure storedProcedure) { var rpc = new CProtoRpc(protoService) { RpcName = storedProcedure.StoredProcedureName, RpcDescription = storedProcedure.StoredProcedureDescription, //DomainModelName = storedProcedure.ResultSetName, DerivedFrom = storedProcedure }; rpc.Request = new CProtoMessage(rpc) { IsRequest = true, MessageName = $"{storedProcedure.StoredProcedureName}Request" }; rpc.Response = new CProtoMessage(rpc) { IsResponse = true, MessageName = $"{storedProcedure.StoredProcedureName}Response" }; var requestMessage = rpc.Request; if (!string.IsNullOrEmpty(storedProcedure.ParameterSetName)) { rpc.Request.ProtoField.Add(new CProtoMessageField(storedProcedure) { IsScalar = false, MessageType = storedProcedure.ParameterSetName, FieldName = storedProcedure.ParameterSetName }); requestMessage = new CProtoMessage(rpc) { IsRequest = true, MessageName = storedProcedure.ParameterSetName }; if (!protoFile.ProtoMessage.Exists(pm => pm.MessageName == requestMessage.MessageName)) { protoFile.ProtoMessage.Add(requestMessage); } } foreach (var parameter in storedProcedure.Parameter) { var field = new CProtoMessageField(parameter) { FieldName = parameter.ParameterName //.SourceColumn.ColumnName, }; if (!parameter.ParameterTypeIsUserDefined) { var sqlType = SqlMapper.ParseValueAsSqlDbType(parameter.ParameterTypeRaw); field.FieldType = SqlMapper.SqlDbTypeToGrpcType(sqlType); } else { //todo: property handle user defined sql types (tables) //lookup table type //for now, use the data type of the first column, assumes single column table var tableType = FindTableType(parameter.ParameterTypeRaw); var converter = new CTableTypeToCClassConverter(); var @class = converter.Convert(tableType.GeneratedTableType); field.FieldType = GrpcType.__string; field.IsScalar = false; field.Repeated = true; field.MessageType = $@"{@class.ClassName}"; if (!protoFile.ProtoMessage.Exists(pm => pm.MessageName == field.MessageType)) { //create a message var tableTypeDerivedMessage = new CProtoMessage(rpc) { MessageName = field.MessageType }; foreach (var property in @class.Property) { var field2 = new CProtoMessageField(property) { FieldName = property.PropertyName, FieldType = SqlMapper.ClrTypeToGrpcType(SqlMapper.ClrTypeAliasToClrType(property.Type)) }; tableTypeDerivedMessage.ProtoField.Add(field2); } protoFile.ProtoMessage.Add(tableTypeDerivedMessage); } } requestMessage.ProtoField.Add(field); } var responseMessage = rpc.Response; if (!string.IsNullOrEmpty(storedProcedure.ResultSetName)) { rpc.Response.ProtoField.Add(new CProtoMessageField(null) { IsScalar = false, Repeated = true, MessageType = storedProcedure.ResultSetName, FieldName = storedProcedure.ResultSetName }); responseMessage = new CProtoMessage(rpc) { IsResponse = true, MessageName = storedProcedure.ResultSetName }; if (!protoFile.ProtoMessage.Exists(pm => pm.MessageName == responseMessage.MessageName)) { protoFile.ProtoMessage.Add(responseMessage); } } foreach (var resultColumn in storedProcedure.ResultSet) { var field = new CProtoMessageField(resultColumn) { FieldName = resultColumn.ColumnName, FieldType = SqlMapper.SqlDbTypeToGrpcType(resultColumn.ColumnSqlDbType) }; responseMessage.ProtoField.Add(field); } return(rpc); }