I'm using dapper to try and send multiple querys at the same time. I have 2 different querys that I want to use. However, no matter what I try, I can only get the method to find 1 of the querys.
Firstly, here's the controller:
[HttpGet]
public async Task<IActionResult> Test(RequestOverview model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
try
{
await _request.Test(model);
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
return Ok();
}
Interface:
Task<bool> Test(RequestOverview model);
Model:
public class TestT
{
public string vehicleRegNr { get; set; } = "";
}
public class TestE
{
public string dealerName { get; set; } = "";
}
Sidenote: The name of the entire class is RequestOverview
Now, here are some of my attempts in the method that uses dapper:
// attempt 1
public async Task<bool> Test(RequestOverview model)
{
string query = #"SELECT TOP 5 RegNumber as vehicleRegNr FROM [dbo].[Vehicle];
SELECT TOP 5 Retailer.Name as dealerName FROM [dbo].[Retailer]";
using (var multi = _sqlconnection.QueryMultiple(query, null))
{
List<TestT> list1 = multi.Read<TestT>().AsList();
List<TestE> list2 = multi.Read<TestE>().AsList();
}
return true;
}
attempt 2//
public async Task<bool> Test(TestT model)
{
string query = #"SELECT TOP 5 RegNumber as vehicleRegNr FROM [dbo].[Vehicle];
SELECT TOP 5 Retailer.Name as dealerName FROM [dbo].[Retailer]";
using (var multi = _sqlconnection.QueryMultiple(query, null))
{
List<dynamic> list1 = multi.Read<dynamic>().AsList();
List<dynamic> list2 = multi.Read<dynamic>().AsList();
}
return true;
}
(In attempt 2 I use only one model class TestT that has vehicleRegNr and dealerName as parameters)
However, no matter what I get this output when debugging:
List 2 always ends up null, anyone knows why?
Thankful for help.
(Sidenote: List 1 contains the vehicleRegNr)
I could not reproduce that problem, created an example https://dotnetfiddle.net/j0L0kd and QueryMultiple works as expected.
And you can see the results:
So I suspect either you check list2 values before multi.Read<dynamic>().AsList(); executed or second query returns nothing :)
Related
I'm creating web-client for my REST API, and I want to add a field to my table containing result of async function.
#foreach(Product item in products)
{
<tr>
<th>#item.Name</th>
<th>#item.Amount</th>
<th>#GetUnit(item.UnitID).Result</th>
<th>#item.PriceNetto</th>
</tr>
}
async Task<string> GetUnit(Guid id)
{
string a = "https://localhost:5001/api/Units/";
a += id.ToString();
var temp = await Http.GetJsonAsync<Unit>(a); //it fails here
return temp.Name;
}
In short I have a list of products and items on the list have "UnitID" property which I use to make a GET request. When I put anywhere in code .Result after my async function result Visual Studio's debugger just skip the line responsible for calling the API and 'bricks' whole app without any error nor exception. Then I have to restart the project.
I tried to create second function only for returning GetUnit(id).Result but it gave nothing. I tried to return whole Unit object and then in the table GetUnit(item.UnitID).Name but it was just representing object (I guess...). I seems like all I need is do it with .Result but when I do it doesn't work.
My API is made with .Net Core 2.2 and my client is made with .Net Core 3.0 (Blazor template). Is this a bug or I just can't do it that way? Thanks.
you shouldn't need to do it.i recommand to call it in async action,like below :
razor focus on view,controller/model focus on data.
public async Task<IActionResult> SomeAction(Guid id)
{
var products = ..;
foreach (var item in products)
{
p.UnitID = await GetUnit(item.UnitID);
}
return View(products);
}
private async Task<string> GetUnit(Guid id)
{
string a = "https://localhost:5001/api/Units/";
a += id.ToString();
var temp = await Http.GetJsonAsync<Unit>(a); //it fails here
return temp.Name;
}
public class Product
{
public string Name { get; set; }
public decimal Amount { get; set; }
public string UnitID { get; set; }
public string PriceNetto { get; set; }
}
IMO, you can't do that way.In blazor,you could get all data in OnInitializedAsync instead.Store all Name in a string List and display the list data in view based index.For example:
#code {
private List<string> listItems = new List<string>();
protected override async Task OnInitializedAsync()
{
//get products
foreach (var product in products)
{
string a = "https://localhost:5001/api/Units/";
a += product.UnitID.ToString();
var temp = await Http.GetJsonAsync<Unit>(a);
listItems.Add(temp.Name);
}
}
}
Razor
#{ int i = 0;}
#foreach(Product item in products)
{
<tr>
<th>#item.Name</th>
<th>#item.Amount</th>
<th> #listItems[i] </th>
<th>#item.PriceNetto</th>
</tr>
i++;
}
I want to return my result as array list. My code looks like this:
public Person Get(string doctorCode)
{
using (PharmaOCEAN_LTEntities entities = new PharmaOCEAN_LTEntities())
{
return entities.Person.FirstOrDefault(e => e.DoctorLicenseNumber == doctorCode);
}
}
Some guy informed me that selected (all) result will be an array, so I tried this way, but im getting an error with select statement:
public IList<Person> Get(string doctorCode)
{
using (PharmaOCEAN_LTEntities entities = new PharmaOCEAN_LTEntities())
{
return entities.Person.Select<Person>(e => e.DoctorLicenseNumber == doctorCode);
}
}
any opinions?
Yeah sure you can!
As a array:
public Person[] Get(string doctorCode)
{
using (PharmaOCEAN_LTEntities entities = new PharmaOCEAN_LTEntities())
{
return entities.Person.Where(e => e.DoctorLicenseNumber == doctorCode).ToArray();
}
}
As a list:
public IEnumerable<Person> Get(string doctorCode)
{
using (PharmaOCEAN_LTEntities entities = new PharmaOCEAN_LTEntities())
{
return entities.Person.Where(e => e.DoctorLicenseNumber == doctorCode).ToList();
}
}
not sure if it compiles, but you get the message :)
Can you provide info error that you get?
Don't you have to add ToList() at the end of select statement?
I am writing to seek help, in how can I filter data and then merge two results, below:
Update code*
public class TestController : ApiController
{
private cdw db = new cdw();
public HttpResponseMessage get([FromUri] Query query)
{
var data = db.data_qy.AsQueryable();
if (query.startDate != null)
{
data = data.Where(c => c.UploadDate >= query.startDate);
}
if (!string.IsNullOrEmpty(query.tag))
{
var ids = query.tag.Split(',');
data = data.Where(c => c.TAG.Any(t => ids.Contains(t)));
}
if (!string.IsNullOrEmpty(query.name))
{
var ids = query.name.Split(',');
data = data.Where(c => c.NAME.Any(t => ids.Contains(t)));
}
if (!data.Any())
{
var message = string.Format("No data found");
return Request.CreateErrorResponse(HttpStatusCode.NotFound, message);
}
return Request.CreateResponse(HttpStatusCode.OK, data);
}
}
entity class:
public partial class data_qy
{
public int ID { get; set; }
public string Name { get; set; }
public string TAG { get; set; }
public string TAG_IS { get; set; }
[Newtonsoft.Json.JsonProperty(PropertyName = "Date")]
public Nullable<System.DateTime> UploadDate { get; set; }
}
Sample Dataset:
Name Tag Tag_IS
AMCAR 2013-5 03065EAC9
ARES 2006-6RA 04009JAA9
ARES 2012-1A 04013TAB9
ATOM 2003-I A 0182690668
BACM 2006-2 AM 05950EAG3
BCAP 2007-AA3 05530VAN9
BCAP 2007-AA3 05530VAN9
BCJAF 9 C 0312888037
BLNDLN 0 0213093627
BLNDLN 0 0213093627
The underlying SQL query should resemble:
select *
from [dbo].[data_qy]
where TAG like '%78473TAC4%'
or TAG LIKE '%05946XYZ0%'
OR NAME LIKE '%TAP%'
OR NAME LIKE '%STORM%'
Using the following list method above, when I run a query such as (api/test/tag=78473,12669,05946,... (30 values)), i get a -- Exception Message:
Some part of your SQL statement is nested too deeply. Rewrite the query or break it up into smaller queries
Am I missing something. Any help would be most appreciated.
Thanks
I'm not in a situation to test this on the spot, but I suspect that either of the following should work:
public class TestController : ApiController
{
private cdw db = new cdw();
public HttpResponseMessage get([FromUri] Query query)
{
IQueryable<data_qy> data = null;
if (!string.IsNullOrEmpty(query.tag))
{
var ids = query.tag.Split(',');
var dataMatchingTags = db.data_qy.Where(c => ids.Any(id => c.TAGS.Contains(id)));
if (data == null)
data = dataMatchingTags;
else
data = data.Union(dataMatchingTags);
}
if (!string.IsNullOrEmpty(query.name))
{
var ids = query.name.Split(',');
var dataMatchingName = db.data_qy.Where(c => ids.Any(id => c.NAME.Contains(id)));
if (data == null)
data = dataMatchingName;
else
data = data.Union(dataMatchingName);
}
if (data == null) // If no tags or name is being queried, apply filters to the whole set of products
data = db.data_qy;
if (query.startDate != null)
{
data = data.Where(c => c.UploadDate >= query.startDate);
}
var materializedData = data.ToList();
if (!materializedData.Any())
{
var message = string.Format("No data found");
return Request.CreateErrorResponse(HttpStatusCode.NotFound, message);
}
return Request.CreateResponse(HttpStatusCode.OK, materializedData);
}
}
I also suspect that you don't need to check against Null in your query, since EF will understand that when transforming the Expression Tree to SQL, but if needed, you can add it.
That would remove the need to use the foreach, the Aggregate and the call to Count. and results in a much simpler query that should use the IN operator in SQL.
Currently you're executing the same query multiple times (the call to .Any at the end will execute the query and then passing the data variable will execute it again. This can be very costly. Instead, materialize the results and act upon that, as above.
I would like to return an image that is dynamically created instead of retrieving from a database or from file. Let's say I have a simple ZipCode class. I would like to have a property that would return an image representation of the zipcode. The JSON returns "ZipAsImage":"System.Drawing.Bitmap".
Yes I am new to the programming in the web world. Yes I have looked for other examples but they seemed to only return an image. Thanks for any help.
public class ZipCode
{
public int ZipCodeId { get; set; }
[NotMapped]
public Image ZipAsImage
{
get
{
// Create a blank iamge for now to test.
return new Bitmap(50, 50);
}
set { }
}
}
My ApiController class
public class ZipCodesController : ApiController
{
private MyContext db = new MyContext();
// GET api/ZipCodesController
public IEnumerable<ZipCode> GetZipCodes()
{
return db.zipcodes.AsEnumerable();
}
// GET api/ZipCodesController/5
public ZipCode GetZipCode(int id)
{
ZipCode zipcode = db.ZipCodes.Find(id);
if (zipcode == null)
{
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
}
return zipcode;
}
...
My Controller class
public class ZipCodesController : Controller
{
private MyContext db = new MyContext();
//
// GET: /ZipCodes/
public ActionResult Index()
{
var zipcodes = db.ZipCodes.Include(z => z.State);
return View(zipcodes.ToList());
}
//
// GET: /ZipCodes/Details/5
public ActionResult Details(int id = 0)
{
ZipCode zipcode = db.ZipCodes.Find(id);
if (zipcode == null)
{
return HttpNotFound();
}
return View(zipcode);
}
...
I dont undersatnd the point where you are showing the MVC Contoller.Am i missing something there? However For Webapi (ApiController) You can re write your Method as follows. This should pass the enitre Object in one response.
public HttpResponseMessage GetZipCode(int id)
{
ZipCode zipcode = db.ZipCodes.Find(id);
if (zipcode == null)
{
return Request.CreateResponse(HttpStatusCode.NotFound)
}
return Request.CreateResponse(HttpStatusCode.OK,zipcode);
}
Sending Binary Images. You need to set Straemcontent and content-type. I found a link that can help you with that Images with Webapi . Look through the entire thread . You might figure out quickly whats missing...
I have a simple List with dummy data as follows:
List<Organisation> list = new List<Organisation>();
list.Add(new Organisation() { LogoUrl = "/images/logos/Blade.png", OrganisationId = 1, OrganisationName = "Blade" });
list.Add(new Organisation() { LogoUrl = "/images/logos/Torn.png", OrganisationId = 2, OrganisationName = "Torn" });
When I run the linq query:
var results = from org in OrganisationsController.GetDummyList()
where org.OrganisationName.StartsWith(searchString)
select org;
It always returns an Empty result. In this case the searchString is specified by the user and the example would be "Tor".
Using different variations like 'where org.OrganisationName == searchString' where the search string is Torn works. But StartsWith never works.
Any ideas where I'm going wrong?
EDIT:
From Jon's code I changed my code to look as follows:
public JsonResult Search(string searchString)
{
//create json result object
JsonResult data = new JsonResult();
var list = OrganisationsController.GetDummyList();
//query the list
var results = from org in list
where org.OrganisationName.ToLower().Contains(searchString.ToLower())
select org;
if (results.Any())
{
System.Diagnostics.Debug.Write("found");
}
//setup the data
data.Data = results;
//return the data
return Json(data, JsonRequestBehavior.AllowGet);
}
Note: I changed the StartsWith to Contains, but both are giving me similary problems.
One of my organisations is called 'Absa'. Here's the really strange thing when I fire up the app for the first time putting in 'bsa' returns nothing, I then enter 'Absa' and it returns a good result. Then I entered 'bsa' again just to double check and it returned Absa which it didn't in the first test. Why would the result not work at first then work later?
Thanks,
Jacques
Unable to reproduce. It works fine for me:
using System;
using System.Collections.Generic;
using System.Linq;
class Organisation
{
public string LogoUrl { get; set; }
// Removed redundant Organisation prefixes
public int Id { get; set; }
public string Name { get; set; }
}
class Test
{
static void Main()
{
// Used collection initializer for sanity
var list = new List<Organisation>
{
new Organisation { LogoUrl = "Blade.png", Id = 1, Name = "Blade" },
new Organisation { LogoUrl = "Torn.png", Id = 2, Name = "Torn" },
};
string searchString = "Tor";
var query = from org in list
where org.Name.StartsWith(searchString)
select org;
// Nicer version:
// var query = list.Where(org => org.Name.StartsWith(searchString));
Console.WriteLine(query.Count()); // 1
}
}
Work out the difference between your code and my code to find out what's wrong.
In particular, you've shown code using List<T>, which means LINQ to Objects. If your real code uses LINQ to SQL or Entity Framework, that could easily affect things.