operator (plus add) in entity framework core send an error - asp.net-core

When using sql select I need a counter for my sequence row like this:
var result = from d in data
select new[]
{
Convert.ToString((count++))
};
but this syntax gives the following error message:
An expression tree may not contain an assignment operator Vehicle.app..NETCoreApp,Version=v1.0

When using LINQ (e.g. from x in data select { ... }) the expression in the selection is translated into a SQL statement and executed in the database. How would an assignment like count++ work in a database? I think you're better off with selecting the records from the database and apply the sequence number on the in memory list of data rather than on the queryable collection which represents the database. For example:
var data = (from d in data select new { ... }).ToList();
var result = data.Select(new { id = Convert.ToString(count++), ... }).ToList();

Related

Modify select identifiers in Sql Query using calcite

I want to modify a SQL query using Calcite. For example
SELECT values FROM data to
SELECT values as v FROM data
I could access SqlNode of select identifier using SqlVisiter implementation.
public Object visit(SqlCall sqlCall) {
SqlNodeList selectList = ((SqlSelect) sqlCall).getSelectList();
for (SqlNode sqlNode : selectList) {
System.out.println(sqlNode.toString());
}
Now what should I do to update SqlNode?
The SqlNode objects in the select list will be instances of SqlIdentifier in this case. So you'll have to cast sqlNode to a SqlIdentifier and then you can call .setName(0, "NEW_NAME"). After this, you call unparse on the original root node to get the new query back.

How can I use a method to add a filter on a property in Entity Framework Core?

I need to conditionally add a filter to particular dates in a query. There are common preconditions and the filter will be the same. Therefore I would like the common code to be in a method which can perform these checks and then have the consumer pass in the property which the filter should be applied to (could be applied to multiple).
Here is a simplified version of my code.
var query = dbContext.Documents.AsQueryable();
query = FilterDocumentsByDate(query, x => x.CreatedDate);
query = FilterDocumentsByDate(query, x => x.SubmittedDate);
private IQueryable<Document> FilterDocumentsByDate(IQueryable<Document> query, Func<Document, DateTime> propertyToSearch)
{
query = query.Where(x => propertyToSearch(x).Year > 2000);
return query;
}
When I look at the query in SQL profiler, I can see that the query is missing the WHERE clause (so all documents are being retrieved and the filter is being done in memory). If I copy/paste the code inline for both dates (instead of calling the method twice) then the WHERE clause for the both dates are included in the query.
Is there no way to add a WHERE condition to an IQueryable by passing a property in a Func which can be properly translated to SQL by Entity Framework?
EF is unable to understand your query, so it breaks and executes WHERE clause in memory.
The solution is creating dynamic expressions.
var query = dbContext.Documents.AsQueryable();
query = FilterDocumentsByDate(query, x => x.CreatedDate.Year);
query = FilterDocumentsByDate(query, x => x.SubmittedDate.Year);
private IQueryable<Document> FilterDocumentsByDate(IQueryable<Document> query, Expression<Func<Document, int>> expression)
{
var parameter = expression.Parameters.FirstOrDefault();
Expression comparisonExpression = Expression.Equal(expression.Body, Expression.Constant(2000));
Expression<Func<Document, bool>> exp = Expression.Lambda<Func<Document, bool>>(comparisonExpression, parameter);
query = query.Where(exp);
return query;
}
I am sorry, I haven't run this myself, but this should create WHERE statement. Let me know how it goes.

Nhibernate and like statement on XML field

I have a wrapped fluent nhibernate framework that I'm reusing and have no control over the actual mapping.
In my entity object I have a property mapped as string to an XML column in sql.
Hence when I run a query like:
var myResult = (from myTable in DataManager.Session.Query<Table>()
where myTable.thatXmlFieldWhichIsMappedAsString.Contains(AnXmlSnippet))
select myTable).FirstOrDefault();
It is trying to use the LIKE operator in SQL which is invalid on that column type.
How can I get around this without having to select all the rows and converting to List first?
In case, that we do not need .Query() (LINQ), and we can use Criteria query or QueryOver, we can use conversion:
// the projection of the column with xml
// casted to nvarchar
var projection = Projections
.Cast(NHibernateUtil.StringClob
, Projections.Property("thatXmlFieldWhichIsMappedAsString"));
// criteria filtering with LIKE
var criteria = Restrictions.Like(projection, "searched xml");
// query and result
var query = session.QueryOver<MyEntity>()
.Where(criteria)
;
var result = query
.SingleOrDefault<MyEntity>()
;
From my experience this could lead to conversion into small nvarchar(255) - sql server... Then we can do it like this:
var projection = Projections
.SqlProjection("CAST(thatXmlFieldWhichIsMappedAsString as nvarchar(max)) AS str"
, new string[]{}
, new NHibernate.Type.IType[]{}
);

dapper sql in-clause throws exception

This may be a duplicate of SELECT * FROM X WHERE id IN (...) with Dapper ORM
I am trying to achieve :
connection.execute("delete from table where id in #ids", new { ids = new int[]{1,2}});
But it's not working. I always get : ERROR: 42883: operator does not exist: integer = integer[].
Even if I do this :
connection.Query<a>("select * from a where a_id in #ids", new { ids = new int[] { 12, 13 } })
I get the same exception.
I am accessing a postgresql database with Npgsql.
Can you tell me what i am doing wrong ?
Here's what happens at the database for the second statement :
Here's some log for the second statement :
operator does not exist: integer = integer[] at character 33
No operator matches the given name and argument type(s). You might need to add explicit type casts.
select * from a where a_id in ((array[12,13])::int4[])
And this is for the first one (same as above but the last line is different)
delete from a where a_id in ((array[12,13])::int4[])
I advise you to take look at the Postgres docs Searching in Arrays.
In brief, you should use the operator "ANY" or "ALL" or manually check the column for each value of the array.
This sql is the equivalent version of a query with the IN clause:
delete from table where id = any (#ids)
var query = "SELECT * FROM lookup WHERE LOWER(discriminator) = ANY(#types)";
_connection.QueryAsync<Lookup>(query, new { types = new[] {"Prefix", "Suffix"} });
This works for me
What worked for me:
connection.Query("select * from a where a_id = ANY(#ids)", new { ids = new int[] { 12, 13 } })

Modeshape querying mixinTypes

I'm using Modeshape and modeshape-connector-jdbc-metadata. I want to get all nodes representing tables in the storage. That nodes have [mj:catalog] mixin type.
I'm querying storage using next code:
public List getDatabases() throws RepositoryException {
// Obtain the query manager for the session ...
QueryManager queryManager = dbSession.getWorkspace().getQueryManager();
// Create a query object ...
Query query = queryManager.createQuery("SELECT * FROM [mj:table]"
, Query.JCR_SQL2);
// Execute the query and get the results ...
QueryResult result = query.execute();
// Iterate over the nodes in the results ...
NodeIterator nodeIter = result.getNodes();
List stringResult = new ArrayList();
while (nodeIter.hasNext()) {
stringResult.add(nodeIter.nextNode().getName());
}
return stringResult;
}
But it always returns empty list.
I also tried to query using next queries:
SELECT unst.*, tbl.* FROM [nt:unstructured] AS unst
JOIN [mj:table] AS tbl ON ISSAMENODE(unst,tbl)
SELECT * FROM [nt:unstructured] WHERE [jcr:mixinTypes] = [mj:table]
But result remains the same.
What I'm doing wrong?
Thank you for any help.
There is a known issue that the database metadata nodes are not indexed automatically. A simple workaround is to cast the JCR Session's getWorkspace() instance to org.modeshape.jcr.api.Workspace (the public API for ModeShape's workspace) and call the reindex(String path) method and passing in the path to the database catalog node (or an ancestor if desired).