I know that in springboot you can call DAO directly from sql string.
I.E
SqlQuery = "
SELECT new com.testProject.model.testDAO(test.country, test.code, sum(case when test.dummy1 = 'POS' then 1 else 0 end), sum(case when test.dummy2 = 'POS' then 1 else 0 end))
FROM test";
But is Possible to Call a DAO from Sql string in C#? I Removed the DAO from the query to make it work:
SqlQuery = "
SELECT test.country, test.code, sum(test.dummy1 = 'POS' ? 1 : 0) as dumm1, sum(test.dummy2 = 'POS' ? 1 : 0) as dummy2
FROM test";
Is there any way to call DAO inside SQL query string?
Since you said you are using azure http trigger with cosmos db input,there is no such DAO mechanism like spring boot with query string param in cosmos db input per my knowledge.
However,based on the example provided on the Azure Function Cosmos Db Input document,it supports using custom Object Class to map the query result from sql. Please refer to my test:
Sample data in cosmos db :
Azure Function Code:
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System.Collections.Generic;
namespace CosmosTriggerCore
{
public static class Function1
{
[FunctionName("Function1")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
[CosmosDB(
databaseName: "db",
collectionName: "coll",
ConnectionStringSetting = "cosmosdbstring",
SqlQuery = "SELECT top 2 * FROM c")]
IEnumerable<TestDoc> testDocItems,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
foreach (TestDoc doc in testDocItems)
{
log.LogInformation(doc.Id);
log.LogInformation(doc.Name);
}
return new OkResult();
}
}
public class TestDoc
{
public string Id { get; set; }
public string Name { get; set; }
}
}
I used TestDoc Class to accept the query result and i can access the properties in the code.
Related
I tried code to execute the Stored Procedure, but I'm facing some issues on my code. help me to solve this error.
Controller
using Employee_API.Data;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Employee_API.Models;
using MySqlConnector;
namespace Employee_API.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class EmpController : Controller
{
private readonly EmpDbContext _empDbContext;
public EmpController(EmpDbContext empDbContext)
{
_empDbContext = empDbContext;
}
[HttpPost("AddEmp")]
public async Task<IActionResult> AddEmp(Employee empRequest)
{
var name = new MySqlParameter("#Name", empRequest.Name);
var empid = new MySqlParameter("#EmpId", empRequest.EmpId);
var design = new MySqlParameter("#Designation", empRequest.Designation);
var dob = new MySqlParameter("#DOB", empRequest.DOB);
var mobile = new MySqlParameter("#Mobile", empRequest.Mobile);
var mail = new MySqlParameter("#Mail", empRequest.Mail);
await _empDbContext.emp_data.ExecuteSqlRaw("EXEC Add_New_Employee #Name, #EmpId, #Designation, #DOB, #Mobile, #Mail", name, empid, design, dob, mobile, mail).ToListAsync();
return Ok(empRequest);
}
}
}
DbContext
using Employee_API.Models;
using Microsoft.EntityFrameworkCore;
namespace Employee_API.Data
{
public class EmpDbContext : DbContext
{
public EmpDbContext(DbContextOptions options) : base(options)
{
}
public DbSet<Employee> emp_data { get; set; }
}
}
Packages
[]
(https://i.stack.imgur.com/JN8Qo.png)
I've tried on many online search, but I couldn't find any solution for this code.
Thanks in Advance.
Running raw SQL is quite the opposite of what's EntityFramework for.
In your code, you're calling ExecureSqlRaw against DBSet, but you should execute it against Database, like this
_empDbContext.Database.ExecuteSqlRaw("...")
I have an Azure function that get an HTTP request , this azure function call a Stored Procedure who update the database,
The Stored Procedure works well and update the table in DB.
But when i ant to simulate this request with postMan i had error(500 :Internal Serveur Erro).
Here is my Function Azure:
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System;
using Core.Handlers;
using System.Text.Json;
using Newtonsoft.Json.Linq;
namespace RealTimeTriggerFunctions
{
public static class SendToAzureSql
{
private static readonly string AZURE_TABLE1=
Environment.GetEnvironmentVariable("AZURE_TABLE1");
// Handler
private static AzureSqlHandler azSqlHandler;
[FunctionName("SendToAzureSql")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
string procedureName = "";
try
{
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
if(string.IsNullOrEmpty(requestBody))
{
return new BadRequestResult();
}
dynamic message = JsonConvert.DeserializeObject(requestBody);
if (message == null)
{
return new BadRequestResult();
}
log.LogInformation((string)message.type.ToString()+ " progress...");
switch (message.type.ToString())
{
case "xx.yy.zz.event.table1.table1":
procedureName = "stored_table1";
InitHandlers(log, AZURE_TABLE1);
break;
default:
return new BadRequestObjectResult("Wrong Request!");
}
var dataJson = JsonDocument.Parse(requestBody);
string actionType = message.type.ToString().Contains("deleted") ? "Deleted": "Default";
await azSqlHandler.UpsertItemAsync(procedureName, actionType, payload:
dataJson.RootElement);
return new OkObjectResult(message.type.ToString() + " Processed");
}
catch (Exception e)
{
log.LogError($"An error occurred while processing request : '{e.Message}'");
throw e;
}
}
/// <summary>
/// Init connexions
/// </summary>
private static void InitHandlers(ILogger log, string connectionString)
{
// Create handler
azSqlHandler = new AzureSqlHandler(log, connectionString);
}
}
}
I call this request in POST : http://localhost:7071/API/SendToAzureSql I get 500.
I found my answer here:
Fetching access token for keyvault
i run az- login in my Azure cli and it Works
I'm attempting to developer an Azure Function App which is triggered by a Http Request and takes the information on said request and added it into a Table in Table Storage. I developed in the portal and have been trying to redo the whole thing locally and publish it to Azure but running into issues with triggering the function and actually having it add to the Table I want it to add too... any help would be really appreciated!
This is what I have so far:
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Microsoft.Azure.WebJobs.Extensions.Http;
namespace LookUpService
{
public static class AddConnectionDetails
{
[FunctionName("AddConnectionDetails")]
public static async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)]HttpRequest req, ILogger log, ICollector<SocietyConnection> lookupTable)
{
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
lookupTable.Add(new SocietyConnection()
{
PartitionKey = data.PartitionKey,
RowKey = data.RowKey,
Connection = data.Connection,
Organisation = data.Organisation
});
return new OkObjectResult($"{data.Organisation}({data.PartitionKey}) {data.RowKey} added to LookUp Table Storage");
}
public class SocietyConnection
{
public string PartitionKey { get; set; }
public string RowKey { get; set; }
public string Connection { get; set; }
public string Organisation { get; set; }
}
}
}
It seems that theres no actual trigger on the function when i've published it and it isnt connecting to the table I want to put stuff into...
Let me know if I've not made anything clear enough!
First, if you develop code on local, you should bebug first. if the function works fine, then publish this function app to azure.
For your requirement, please use below code, it works fine on my side:
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Microsoft.WindowsAzure.Storage.Table;
namespace FunctionApp49
{
public class LogEntity : TableEntity
{
public string OriginalName { get; set; }
}
public static class Function1
{
[FunctionName("Function1")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
[Table("AzureWebJobsHostLogscommon")] CloudTable cloudTable,
ILogger log)
{
log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
TableQuery<LogEntity> rangeQuery = new TableQuery<LogEntity>().Where(
TableQuery.CombineFilters(
TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal,
"FD2"),
TableOperators.And,
TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.GreaterThan,
"t")));
// Execute the query and loop through the results
foreach (LogEntity entity in
await cloudTable.ExecuteQuerySegmentedAsync(rangeQuery, null))
{
log.LogInformation(
$"{entity.PartitionKey}\t{entity.RowKey}\t{entity.Timestamp}\t{entity.OriginalName}");
}
return new OkObjectResult("111111111111111111");
}
}
}
Have a look of this doc:
https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-table?tabs=csharp#cloudtable
I am currently following this guide (https://learn.microsoft.com/en-us/azure/azure-functions/functions-test-a-function) for adding testing to my Azure Functions application.
Currently I have built out 8 Azure Functions which all work well, I have also added a Functions.Tests project and referenced the Azure Functions project within it.
Here is what the Functions.Tests currently look like.
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Xunit;
namespace Functions.Tests
{
public class FunctionsTests
{
private readonly ILogger logger = TestFactory.CreateLogger();
[Fact]
public async void Http_trigger_should_return_known_string()
{
var request = TestFactory.CreateHttpRequest("name", "Bill");
var response = (OkObjectResult)await HttpFunction.Run(request, logger);
Assert.Equal("Hello, Bill", response.Value);
}
[Theory]
[MemberData(nameof(TestFactory.Data), MemberType = typeof(TestFactory))]
public async void Http_trigger_should_return_known_string_from_member_data(string queryStringKey, string queryStringValue)
{
var request = TestFactory.CreateHttpRequest(queryStringKey, queryStringValue);
var response = (OkObjectResult)await HttpFunction.Run(request, logger);
Assert.Equal($"Hello, {queryStringValue}", response.Value);
}
[Fact]
public void Timer_should_log_message()
{
var logger = (ListLogger)TestFactory.CreateLogger(LoggerTypes.List);
TimerTrigger.Run(null, logger);
var msg = logger.Logs[0];
Assert.Contains("C# Timer trigger function executed at", msg);
}
}
}
However I am getting the following errors within FunctionsTests.cs
I have tried all the suggested fixes from Visual Studio and checked resources online but with no luck. Perhaps I am missing a reference? I'm not sure as I have followed the guide word for word.
Example Azure Function used:
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
namespace Exemplar
{
public static class getCase
{
[FunctionName("getCase")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", Route = "v1/case/caseId")] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
string name = req.Query["name"];
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
name = name ?? data?.name;
return name != null
? (ActionResult)new OkObjectResult($"Hello, {name}")
: new BadRequestObjectResult("Please pass a name on the query string or in the request body");
}
}
}
Assuming provided project that contains the function is referenced, the test simply needs to arrange and exercise the target function as shown in the linked example
[Fact]
public async Task getCase_should_return_known_string()
{
var request = TestFactory.CreateHttpRequest("name", "Bill");
var response = (OkObjectResult)await getCase.Run(request, logger);
Assert.Equal("Hello, Bill", response.Value);
}
[Theory]
[MemberData(nameof(TestFactory.Data), MemberType = typeof(TestFactory))]
public async Task getCase_should_return_known_string_from_member_data(string queryStringKey, string queryStringValue)
{
var request = TestFactory.CreateHttpRequest(queryStringKey, queryStringValue);
var response = (OkObjectResult)await getCase.Run(request, logger);
Assert.Equal($"Hello, {queryStringValue}", response.Value);
}
Also avoid using async void. Refactor those tests to use async Task instead.
Seems to me it's missing a reference to your azure functios project, make sure you've added the reference by:
right clicking your test project
select the menu Add
select Reference
select the projects tab (left menu), then mark the checkbox of your function project
click ok
Is it possible to (input) bind to table storage within an http-triggered function?
I'm attempting to add an input-binding to table-storage inside of a regular http-triggered function with the following attribute:
[Table("MyTable", "MyPartition", "{httpTrigger}")] MyPoco poco
However it's returning the following error when I execute it:
[6/5/2019 5:36:38 PM] An unhandled host error has occurred. [6/5/2019
5:36:38 PM] Microsoft.Azure.WebJobs.Host:
'tableStorageInputBindingHttpTriggered' can't be invoked from Azure
WebJobs SDK. Is it missing Azure WebJobs SDK attributes?.
Additionally at startup, I get this exception:
[6/5/2019 6:17:17 PM] tableStorageInputBindingHttpTriggered: Microsoft.Azure.WebJobs.Host: Error indexing method 'tableStorageInputBindingHttpTriggered'. Microsoft.Azure.WebJobs.Host: Unable to resolve binding parameter 'httpTrigger'. Binding expressions must map to either a value provided by the trigger or a property of the value the trigger is bound to, or must be a system binding expression (e.g. sys.randguid, sys.utcnow, etc.).
Here's the full function:
public class MyPoco
{
public string PartitionKey { get; set; }
public string RowKey { get; set; }
public string Directory { get; set; }
}
public static class tableStorageInputBindingHttpTriggered
{
[FunctionName("tableStorageInputBindingHttpTriggered")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
[Table("MyTable", "MyPartition", "{httpTrigger}")] MyPoco poco,
ILogger log)
{
string name = req.Query["name"];
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
name = name ?? data?.name;
return name != null
? (ActionResult)new OkObjectResult($"PK={poco.PartitionKey}, RK={poco.RowKey}, Text={poco.Directory}")
: new BadRequestObjectResult("");
}
}
What am I doing wrong? How do I bind to table storage within an http-triggered azure-function?
Issue is that http trigger returns you an object so it dont know how to extract your key.
You need to use route, which will tell Function how to get parameter and then you will be able to use that parameters
public static async Task<HttpResponseMessage> SetLatestAsync(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "release-set-latest/{program}")]
HttpRequestMessage req,
string program,
[Table(TableName, "latest", "{program}")]FlymarkLatestVersion pocos)
This inserts the request body to Table storage by binding to CloudTable
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.WindowsAzure.Storage.Table;
namespace AzureFunctionsSandbox
{
public class MyPoco : TableEntity
{
public string Body { get; set; }
}
public static class Function1
{
[FunctionName("Function1")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
[Table("Sandbox", "StorageConnectionString")] CloudTable table,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
var poco = new MyPoco { PartitionKey = "HttpTrigger", RowKey = Guid.NewGuid().ToString(), Body = requestBody };
var insertOperation = TableOperation.Insert(poco);
await table.ExecuteAsync(insertOperation);
return new OkObjectResult($"PK={poco.PartitionKey}, RK={poco.RowKey}, Text={poco.Body}");
}
}
}
Note: MyPoco inherits from TableEntity which allows you to create the TableOperation.Insert(poco) as .Insert() takes an ITableEntity.
local.settings.json
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet",
"StorageConnectionString": "UseDevelopmentStorage=true"
}
}
Seems you are trying to read your Azure Table Storage from HTTP Trigger Function. Please have a look on the code snippet below:
Your POCO Class:
public class MyPoco
{
public string PartitionKey { get; set; }
public string RowKey { get; set; }
public string Directory { get; set; }
}
Table Storage Class:
public class TableStorageClass
{
public TableStorageClass()
{
}
public TableStorageClass(DynamicTableEntity entity)
{
PartitionKey = entity.PartitionKey;
RowKey = entity.RowKey;
}
public string PartitionKey { get; set; }
public string RowKey { get; set; }
}
Azure HTTP Trigger Function V2:
public static class FunctionReadFromTableStorage
{
[FunctionName("FunctionReadFromTableStorage")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
//Read Request Body
var content = await new StreamReader(req.Body).ReadToEndAsync();
//Extract Request Body and Parse To Class
MyPoco objMyPoco = JsonConvert.DeserializeObject<MyPoco>(content);
// Validate param because PartitionKey and RowKey is required to read from Table storage In this case , so I am checking here.
dynamic validationMessage;
if (string.IsNullOrEmpty(objMyPoco.PartitionKey))
{
validationMessage = new OkObjectResult("PartitionKey is required!");
return (IActionResult)validationMessage;
}
if (string.IsNullOrEmpty(objMyPoco.RowKey))
{
validationMessage = new OkObjectResult("RowKey is required!");
return (IActionResult)validationMessage;
}
// Table Storage operation with credentials
var client = new CloudTableClient(new Uri("https://YourStorageURL.table.core.windows.net/"),
new Microsoft.WindowsAzure.Storage.Auth.StorageCredentials("YourStorageName", "xtaguZokAWbfYG4QDkBjT+YourStorageKey+T/kId/Ng+cl3TfYHtg=="));
var table = client.GetTableReference("YourTableName");
//Query filter
var query = new TableQuery()
{
FilterString = string.Format("PartitionKey eq '{0}' and RowKey eq '{1}'", objMyPoco.PartitionKey, objMyPoco.RowKey)
};
//Request for storage query with query filter
var continuationToken = new TableContinuationToken();
var storageTableQueryResults = new List<TableStorageClass>();
foreach (var entity in table.ExecuteQuerySegmentedAsync(query, continuationToken).GetAwaiter().GetResult().Results)
{
var request = new TableStorageClass(entity);
storageTableQueryResults.Add(request);
}
//As we have to return IAction Type So converting to IAction Class Using OkObjectResult We Even Can Use OkResult
var result = new OkObjectResult(storageTableQueryResults);
return (IActionResult)result;
}
}
Point To Remember:
In case of Azure Portal execution just get rid of FunctionReadFromTableStorage class
You need following reference to execute above code
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Microsoft.WindowsAzure.Storage.Table;
using System.Collections.Generic;
Postman Request Pattern:
Function Invoke Sample:
{
"PartitionKey": "Your Param According to Table Storage Design" ,
"RowKey": "Your Param According to Table Storage Design",
"Directory": "Your Param According to Table Storage Design"
}
See the screenshot:
Postman response:
Response is subject to my own table design
[
{
"partitionKey": "Microsoft SharePoint Server",
"rowKey": "2016"
}
]
See the screenshot below:
Note: I like to write code in simple and readable way. I just tried it for your case. If it resolved your issue my effort would be success then. This is the easiest way I know so far to read from
Azure table storage.