I'm not sure whether it is an emulator issue or not but i have a really simple query
var collectionUri = UriFactory.CreateDocumentCollectionUri(Constants.CosmosDbName, CollectionName);
var spec = new SqlQuerySpec()
{
QueryText = "SELECT * FROM Users u WHERE u.firstName = #firstname",
Parameters = new SqlParameterCollection
{
new SqlParameter{
Name = "#firstname",
Value = value
}
}
};
var query = client.CreateDocumentQuery<User>(collectionUri, spec);
var users = await query.ToListAsync();
the parametrized query returns no results i.e. 0 users
while the same plain query below retuns 1 user that matches the WHERE condition:
spec.Parameters.Clear();
spec.QueryText = $"SELECT * FROM Users u WHERE u.firstName = '{value}'";
query = client.CreateDocumentQuery<User>(collectionUri, spec);
users = await query.ToListAsync(); // returns 1 user
do I need somehow explicitly enable parameterized queries
or am I doing something wrong above with a parameterized query?
According to the Syntax, your query should be like this,
SqlQuerySpec sqlQuerySpec = new SqlQuerySpec
{
QueryText = #"SELECT *
FROM Users u
WHERE u.u.firstName = #firstname",
Parameters = new SqlParameterCollection
{
new SqlParameter("#firstname", value)
}
};
The issue is a kind of var pitfall
the SqlParameter value was taken from an Azure function HttpRequest request:
var value = req.Query["firstname"];
which is
Microsoft.Extensions.Primitives.StringValues value = req.Query["firstname"];
When SqlParameter is created with value of StringValues type it makes slightly different query:
SELECT * FROM Users u WHERE u.firstName = ['Dima']
the brackets ['Dima'] here are excess
the correct query must be without brackets
SELECT * FROM Users u WHERE u.firstName = 'Dima'
so to fix the parameterized query the parameter value should be a string
new SqlParameter("#firstname",value.ToString())
Related
I am trying to make a login page. When I try to receive the userdata with linq I get an exception because I try to use Parse in my query. I searched a bit online and found out it is because Linq doesn't recognize Parse. From what I understand I have to translate the not recognisable code to code that linq/slq recognises. Since I have just started using linq queries I have no idea how to accomplish this.
My query:
public static UserDetails GetUser(UserDetails userde)
{
var usr = from u in db.Users
join r in db.Roles on u.RoleId equals r.IdRole
where u.Email == userde.Email && u.Active == true
select new UserDetails
{ Firstname = u.Firstname,
Surname = u.Surname,
Email = u.Email,
Function = u.Function,
Password = u.Password,
Salt = u.Salt,
Userroles = (UserRoles)Enum.Parse(typeof(UserRoles), r.Role1)
};
return usr.FirstOrDefault();
}
I checked these articles:
linq to entities does not recognize method
linq to entities does not recognize the methods system object parsesystem type
you should first use FirstOrDefault() and parse it later. Otherwise linq is still trying to build the select-statement. After FirstOrDefault (or ToList,...) you have your result and can then parse it without problems.
Should be something like this:
public static UserDetails GetUser(UserDetails userde)
{
var usr = from u in db.Users
join r in db.Roles on u.RoleId equals r.IdRole
where u.Email == userde.Email && u.Active == true
select new UserDetails { Firstname = u.Firstname,
Surname = u.Surname,
Email = u.Email,
Function = u.Function,
Password = u.Password,
Salt = u.Salt,
// store the database-value in another property
UserrolesUnparsed = r.Role1
};
// get the database-results
UserDetails details = usr.FirstOrDefault();
// parse the database-value and set it to the property you want to
details.Userroles = (UserRoles)Enum.Parse(typeof(UserRoles), details.UserrolesUnparsed);
return details;
}
sure, there are better/cleaner methods, but this is just to explain you.
I'm using DynamoDB to query a table with the following commands
QueryRequest request = new QueryRequest
{
TableName = "Events",
ExclusiveStartKey = startKey,
KeyConditions = keyConditions,
IndexName = "Title-index" // Specify the index to query against
};
// Issue request
QueryResponse result = client.Query(request);
The ExclusiveStartKey and Keyconditions are predefined
The issue is that the QueryResult result variable is not parsed to my native object, when I use the DynamoDB.Context you cast the method with the expected type, but in this case I need to parse the QueryResult...
Is there any other way to do this?
Or should I parse the object?
I ended up using something like:
using System.Linq;
...
// Issue request
QueryResponse result = AmazonDynamoDBClient.Query(request);
var items = result.Items.FirstOrDefault();
var doc = Document.FromAttributeMap(items);
var myModel = DynamoDBContext.FromDocument<MyModelType>(doc);
What you want is some sort of ORM - a nice read is Using Amazon DynamoDB Object Persistence Framework. Also check out the API reference that also shows samples
Take a look at the examples from Querying Tables Using the AWS SDK for .NET Low-Level API documentation
In your handling method
var response = client.Query(request);
var result = response.QueryResult;
foreach (Dictionary<string, AttributeValue> item in response.QueryResult.Items)
{
// Process the result.
PrintItem(item);
}
PrintItem implementation
private static void PrintItem(Dictionary<string, AttributeValue> attributeList)
{
foreach (KeyValuePair<string, AttributeValue> kvp in attributeList)
{
string attributeName = kvp.Key;
AttributeValue value = kvp.Value;
Console.WriteLine(
attributeName + " " +
(value.S == null ? "" : "S=[" + value.S + "]") +
(value.N == null ? "" : "N=[" + value.N + "]") +
(value.SS == null ? "" : "SS=[" + string.Join(",", value.SS.ToArray()) + "]") +
(value.NS == null ? "" : "NS=[" + string.Join(",", value.NS.ToArray()) + "]")
);
}
Console.WriteLine("************************************************");
}
I was stuck on the same issue, and found that by using Table.Query with a QueryOperationConfig I could specify the index that I wanted to use. Because the Document object returned from this query has a "ToJson()" method on it, I was able to convert the results of the query to Json, and then use Json.Net to Deserialize it back into my object which worked flawlessly for my totally flat object.
var queryFilter = new QueryFilter(indexedColumnName, QueryOperator.Equal, targetValue);
Table table = Table.LoadTable(client, Configuration.Instance.DynamoTable);
var search = table.Query(new QueryOperationConfig { IndexName = indexName, Filter = queryFilter });
List<MyObject> objects = new List<MyObject>();
List<Document> documentSet = new List<Document>();
do
{
documentSet = search.GetNextSetAsync().Result;
foreach (var document in documentSet)
{
var record = JsonConvert.DeserializeObject<MyObject>(document.ToJson());
objects .Add(record);
}
} while (!search.IsDone);
Hope it helps you out!
I have a URL which which has a query parameter that itself contains a query string with other parameters. E.g:
https://discovery.com/disco.ashx?entityId=www.test.com&return=https://myidp.com/?param1=myvalue
How do I get the value of the nested param1?
I have tried something like this but it doesn't work:
var returnParam = context.Request.QueryString["return"];
var test = HttpUtility.ParseQueryString(returnParam);
var value = test["param1"];
you can try this - var u = new Uri(returnParam); var newparams = u.Query;
HttpUtility.ParseQueryString expects only the query string as input.
Extract the query string from the url using Uri and then pass that to HttpUtility.ParseQueryString
var uri = new Uri(Request.QueryString["return"]);
var queryParams = HttpUtility.ParseQueryString(uri.Query);
var value = queryParams["param1"];
The following query is working successfully.
var tabs = (
from r in db.TabMasters
orderby r.colID
select new { r.colID, r.FirstName, r.LastName })
.Skip(rows * (page - 1)).Take(rows);
Now I want to return JsonResult as like
var jsonData = new
{
total = (int)Math.Ceiling((float)totalRecords / (float)rows),
page = page,
records = totalRecords,
rows = (from r in tabs
select new { id = r.colID, cell = new string[] { r.FirstName, r.LastName } }).ToArray()
};
return Json(jsonData, JsonRequestBehavior.AllowGet);
But it will gives me an error like:
The array type 'System.String[]' cannot be initialized in a query result. Consider using 'System.Collections.Generic.List`1[System.String]' instead.
What should I do to get expected result?
I suspect that it's as simple as pushing the last part into an in-process query using AsEnumerable():
var jsonData = new
{
total = (int)Math.Ceiling((float)totalRecords / (float)rows),
page = page,
records = totalRecords,
rows = (from r in tabs.AsEnumerable()
select new { id = r.colID,
cell = new[] { r.FirstName, r.LastName } }
).ToArray()
};
return Json(jsonData, JsonRequestBehavior.AllowGet);
You may want to pull that query out of the anonymous type initializer, for clarity:
var rows = tabs.AsEnumerable()
.Select(r => new { id = r.colID,
cell = new[] { r.FirstName, r.LastName })
.ToArray();
var jsonData = new {
total = (int)Math.Ceiling((float)totalRecords / (float)rows),
page,
records = totalRecords,
rows
};
It's because it's adding to the LINQ query that is your tabs IQueryable. That is then trying to turn the LINQ expression into a SQL query and the provider doesn't support projecting arrays.
You can either change the assignment of the tabs variable's LINQ expression to use ToList to materialize the DB results right then and there, or you can add .AsEnumerable() to the LINQ expression assigned to the rows field of the anonymous type that is your JsonResult. AsEnumerable will demote the IQueryable to an IEnumerable which will prevent your second LINQ query from trying to be added to the DB query and just make it a LINQ-to-objects call like it needs to be.
What am I doing wrong?
Trying to pass in my DataTable to a stored proc using LINQ. Below is my code.
var sqlCommand = new System.Data.SqlClient.SqlCommand {
CommandType = System.Data.CommandType.StoredProcedure,
CommandText = "UserIdList"
};
var dataTable = new System.Data.DataTable("IdList");
dataTable.Columns.Add("AttributeIds", typeof(Int32));
dataTable.Rows.Add(26);
dataTable.Rows.Add(40);
dataTable.Rows.Add(41);
dataTable.Rows.Add(45);
dataTable.Rows.Add(78);
dataTable.Rows.Add(33);
dataTable.Rows.Add(36);
//The parameter for the SP must be of SqlDbType.Structured
var parameter = new System.Data.SqlClient.SqlParameter {
ParameterName = "#AttributeIds",
SqlDbType = System.Data.SqlDbType.Structured,
TypeName = "ecs.IDList",
Value = dataTable,
};
sqlCommand.Parameters.Add(parameter);
var user = myDC.DC.ExecuteQuery("exec ecs.udpUserAttributeDetails {0}, {1}", sqlCommand, userId).SingleOrDefault();
This seems to be the problem
var user = myDC.DC.ExecuteQuery("exec ecs.udpUserAttributeDetails {0}, {1}", sqlCommand, userId).SingleOrDefault();
In your code, you are passing a sqlCommand object as the first parameters and the userId as the 2nd parameter.
A data context ExecuteQuery method has 2 overloads
ExecuteQuery<TResult>(String, Object[])
ExecuteQuery(Type, String, Object[])
You seem to be using Overload 1 - i.e. ExecuteQuery<TResult>(String, Object[]) but in that case you need to specify the type of the returned object
eg :-
var customers = db.ExecuteQuery<Customer>(#"SELECT CustomerID, CompanyName, ContactName FROM dbo.Customers WHERE City = {0}", "London");
NOTE: db.ExecuteQuery<Customer> in the above example is what I am referring to.
I think this might be the cause of the error as the compiler is mapping your request to overload 2 instead which doesnt return any values but takes in 3 parameters resulting in your A query parameter cannot be of type 'System.Data.SqlClient.SqlCommand error.