Automapper Project().To Error A query body must end with a select - automapper

I'm trying to prevent that a query to an entity bring more columns than necessary. Should only bring those columns specified in the target model.
Below is my code built following some examples to achieve my goal but I get syntax error "A query body must end with a select clause or a group clause linq”
int the query line.
var studentEventsModel = from c in DbContext.StudentEvent.Project().To<StudentEventViewModel>();
Please let me know what I’m doing wrong.
public IEnumerable<StudentEventViewModel> GetStudentEventsListViewModel()
{
Mapper.CreateMap<StudentEvent, StudentEventViewModel>();
var studentEventsModel = from c in DbContext.StudentEvent.Project().To<StudentEventViewModel>();
return studentEventsModel;
}

As #hometoast mentioned you may add select at the end of your query like this:
var studentEventsModel =
from c in DbContext.StudentEvent.Project().To<StudentEventViewModel>() select c;
or alerternatively you may use the lambda expression like this:
var studentEventsModel = DbContext.StudentEvent.Project().To<StudentEventViewModel>();
And as to the question on why you are seeing that error, it is due to the fact that a query syntax must end with select or group, mentioned here in the documentation.
A query expression must begin with a from clause and must end with a
select or group clause. Between the first from clause and the last
select or group clause, it can contain one or more of these optional
clauses: where, orderby, join, let and even additional from clauses.
You can also use the into keyword to enable the result of a join or
group clause to serve as the source for additional query clauses in
the same query expression.

Related

CQL query to return a boolean column based on a condition

Is it possible to retrieve a true/false answer from a CQL query that checks a condition -- for example, if a collection has a specific value?
Consider:
CREATE TABLE Test (Id text PRIMARY KEY, Roles set<text>)
INSERT INTO Test(Id, Roles)
VALUES ('123', {'Driver', 'Pilot', 'Janitor'})
I would like to get a true or false value depending on whether or not the set associated with Id='123' contains a specific value. Here is an imaginary syntax for what I'd like to get; it does not work:
SELECT
Roles CONTAINS 'Pilot' // <<== Not a valid syntax; this does not work
FROM Test
WHERE Id = '123'
Ok, here's what I came up with in the airport, quick...
Unfortunately, Cassandra CQL doesn't have a lot of the things that folks have grown accustomed to in SQL. For the problem of querying by id and roles CONTAINS 'Pilot', I came up with a similar solution.
CREATE TABLE roles (Id text, Roles set<text>);
CREATE INDEX on roles(roles);
Although, I used a secondary index to permit filtering on the roles collection.
The boolean is a little trickier. I created a user defined function (setting user_defined_functions_enabled: true in my cassandra.yaml).
Then the UDF:
CREATE OR REPLACE FUNCTION textToBoolean (input TEXT)
RETURNS NULL ON NULL INPUT RETURNS BOOLEAN
LANGUAGE java AS 'if (!input.equals("True")) { return false; }
return Boolean.valueOf(input);';
And then this works:
SELECT texttoboolean('True') AS success FROM roles WHERE id='123' AND roles CONTAINS 'Pilot';
success
---------
True
(1 rows)
All the UDF really does is let you return a boolean True if you really need to. So it returns true if it works, but returns nothing if it doesn't. Your solution of returning the COUNT might work better depending on what you're trying to accomplish.
It is possible to obtain a 1 or 0 result using COUNT:
SELECT COUNT(*)
FROM Test
WHERE Id = '123' AND Roles CONTAINS 'Pilot'
ALLOW FILTERING
You need ALLOW FILTERING to suppress a performance warning.

Writing a subquery to display records in a grid

I have two DAC's POReceipt, and and POReceiptLine. POReceiptLine containts a field called MfrPartNbr.
I want the user to be able to lookup all the POReceipts where the POReceiptLine.MfrPartNbr is equal to an entered value.
The SQL would be
SELECT *
FROM dbo.POReceipt
WHERE POReceipt.ReceiptNbr IN
(
SELECT ReceiptNbr
FROM dbo.POReceiptLine
WHERE MfrPartNbr = 'MY_ENTERED_PART_NBR'
)
Any idea how to write the BQL Statement for this?
As stated, an inner join won't work in this case because you will receive the same POReceipt multiple times (once for each POReceiptLine). The following BQL query shows how you can get the desired results using a sub query. If mfrPartNbr is an extension field, then replace POReceiptLine.mfrPartNbr with the correct extension name (e.g. POReceiptLineExtension.mfrPartNbr).
PXSelect<POReceipt, Where<Exists<
Select<POReceiptLine,
Where<POReceiptLine.receiptNbr, Equal<POReceipt.receiptNbr>,
And<POReceiptLine.mfrPartNbr, Equal<Required<POReceiptLine.mfrPartNbr>>>>>>>>.Select(this, "MY_ENTERED_PART_NBR");

Kentico Repeater with Custom Query

OK Here we go.
Using Kentico 11/Portal Engine (no hot fixes)
Have a table that holds Content only page Types. One field of importance is a Date and time field.
I am trying to get rows out of this table that match a certain month and year criteria. For instance give me all records where Month=2 and Year=2018. These argument will be passed via the query string
I have a custom Stored proc that I would like to receive two int(or string) arguments then return a collection of all matching rows.
I am using a RepeaterWithCustomQuery to call the procedure and handle the resulting rows. As you can see below the querystring arguments are named "year" and "monthnumber".
The Query
Me.PR.PREDetailSelect
When my Webpart is set up in this configuration I get the following error:
In my Query, I have tried:
EXEC Proc_Custom_PRDetails #MonthNumber = ##ORDERBY##; #Year = ##WHERE##<br/>
EXEC Proc_Custom_PRDetails #MonthNumber = ##ORDERBY##, #Year = ##WHERE##<br/>
EXEC Proc_Custom_PRDetails #MonthNumber = ##ORDERBY## #Year = ##WHERE##<br/>
Any help would be appreciated (Thanks in advance Brendan). Lastly, don't get too caught up in the names of specific objects as I tried to change names to protect the innocent.
Those macros for queries are not meant to be used with stor procs. The system generates this false condition 1=1 in case if you don't pass anything so it won't break the sql statement like the one below:
SELECT ##TOPN## ##COLUMNS##
FROM View_CMS_Tree_Joined AS V
INNER JOIN CONTENT_MenuItem AS C
ON V.DocumentForeignKeyValue = C.MenuItemID AND V.ClassName = N'CMS.MenuItem'
WHERE ##WHERE##
ORDER BY ##ORDERBY##
You need to convert you stor proc to SQL statement then you can use these SQL macros or use stor proc without parameters
If look at the query above top and where are not good because system will do adjustment, but you can use order by and columns, but they both must be present (I think it passes them as is):
exec proc_test ##ORDERBY##, ##COLUMNS##
Honestly I would advice against doing this, plus you won't gain much by calling stor proc.

Nested subquery in FOR ALL ENTRIES

Consultant sent me this code example, here is something he expects to get
SELECT m1~vbeln_im m1~vbelp_im m1~mblnr smbln
INTO CORRESPONDING FIELDS OF TABLE lt_mseg
FROM mseg AS m1
INNER JOIN mseg AS m2 ON m1~mblnr = m2~smbln
AND m1~mjahr = m2~sjahr
AND m1~zeile = m2~smblp
FOR ALL ENTRIES IN lt_vbfa
WHERE
AND m2~bwart = '102'
AND 0 = ( select SUM( ( CASE
when SHKZG = 'S' THEN 1
when SHKZG = 'H' THEN -1
else 0
END ) *MENGE ) MENGE
into lt_mseg-summ
from mseg
where
VBELN_IM = m1~vbeln_im
and VBELP_IM = m1~vbelp_im
).
The problem is I don't see how that should work in current syntax. I think about deriving internal select and using it as condition to main one, but is there a proper way to write this nested construction?
As i get it, if nested statement = 0, then main query executes. The problem here is the case inside nested statement. Is it even possible in ABAP? And in my opinion this check could be used outside from main SQL query.
Any suggestions are welcome.
the logic that you were given is part of Native/Open SQL and has some shortcomings that you need to be aware of.
the statement you are showing has to be placed between EXEC SQL and ENDEXEC.
the logic is platform dependent.
there is no syntax checking performed between the EXEC and ENDEXEC
the execution of this bypasses the database buffering process, so its slower
To me, I would investigate a better way to capture the data that performs better outside of open/native sql.
If you want to move forward with this type of logic, below are a couple of links which should be helpful. There is an example select using a nested select with a case statement.
Test Program
Example Logic
This is probably what you need, it works at least since ABAP 750.
SELECT vbeln UP TO 100 ROWS
FROM vbfa
INTO TABLE #DATA(lt_vbfa).
DATA(rt_vbeln) = VALUE range_vbeln_va_tab( FOR GROUPS val OF <line> IN lt_vbfa GROUP BY ( low = <line>-vbeln ) WITHOUT MEMBERS ( sign = 'I' option = 'EQ' low = val-low ) ).
SELECT m1~vbeln_im, m1~vbelp_im, m1~mblnr, m2~smbln
INTO TABLE #DATA(lt_mseg)
FROM mseg AS m1
JOIN mseg AS m2
ON m1~mblnr = m2~smbln
AND m1~mjahr = m2~sjahr
AND m1~zeile = m2~smblp
WHERE m2~bwart = '102'
AND m1~vbeln_im IN ( SELECT vbelv FROM vbfa WHERE vbelv IN #rt_vbeln )
GROUP BY m1~vbeln_im, m1~vbelp_im, m1~mblnr, m2~smbln
HAVING SUM( CASE m1~shkzg WHEN 'H' THEN 1 WHEN 'S' THEN -1 ELSE 0 END * m1~menge ) = 0.
Yes, aggregating and FOR ALL ENTRIES is impossible in one SELECT, but you can trick the system with range and subquery. Also you don't need three joins for summarizing reversed docs, your SUM subquery is redundant here.
If you need to select documents not only by delivery number but also by position this will be more complicated for sure.

Astyanax parepared statement withvalues() not working properly

today I migrated to Astyanax 1.56.42 and discovered, that withValues() on prepared statements doesn't seem to work properly with SQL SELECT...WHERE...IN ().
ArrayList<ByteBuffer> uids = new ArrayList<ByteBuffer>(fileUids.size());
for (int i = 0; i < fileUids.size(); i++) {
uids.add(ByteBuffer.wrap(UUIDtoByteArray(fileUids.get(i)), 0, 16));
}
result = KEYSPACE.prepareQuery(CF_FILESYSTEM)
.withCql("SELECT * from files where file_uid in (?);")
.asPreparedStatement()
.withValues(uids)
.execute();
If my ArrayList contains more than one entry, this results in error
SEVERE: com.netflix.astyanax.connectionpool.exceptions.BadRequestException: BadRequestException: [host=hostname(hostname):9160, latency=5(5), attempts=1]InvalidRequestException(why:there were 1 markers(?) in CQL but 2 bound variables)
What am I doing wrong? Is there any other way to handle a SQL SELECT...WHERE...IN () - statement or did I find a bug?
Best regards
Chris
As you mentioned because you are supplying a collection (ArrayList) to a single ? Astyanax throws an exception. I think you need to add a ? for each element you want to have inside the IN clause.
Say you want to have 2 ints stored in an ArrayList called arrayListObj the where clause, your statement looks like this:
SELECT & FROM users WHERE somevalue IN (arrayListObj);
Because you are suppling a collection, this cant work, so you will need multiple ?'s. I.e. you want :
SELECT name, occupation FROM users WHERE userid IN (arrayListObj.get(0), arrayListObj.get(1));
I couldn't find anything on the Astyanax wiki about using the IN clause with prepared statements.

Resources