Kentico Repeater with Custom Query - kentico

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.

Related

How to query fields with multiple values in Azure Cognitive Search

Working on Azure Cognitive Search with backend as MS SQL table, have some scenarios where need help to define a query.
Sample table structure and data :
Scenarios 1 : Need to define a query which will return data based on category.
I have tied query using search.ismatch but its uses prefix search and matches other categories as well with similar kind of values i.e. "Embedded" and "Embedded Vision"
$filter=Region eq 'AA' and search.ismatch('Embedded*','Category')
https://{AZ_RESOURCE_NAME}.search.windows.net/indexes/{INDEX_NAME}/docs?api-version=2020-06-30-Preview&$count=true&$filter=Region eq 'AA' and search.ismatch('Embedded*','Category')
And it will response with below result, where it include "Embedded" and "Embedded Vision" both categories.
But my expectation is to fetch data only if it match "Embedded" category, as highlighted below
Scenario 2: For the above Scenario 1, Need little enhancement to find records with multiple category
For example if I pass multiple categories (i.e. "Embedded" , "Automation") need below highlighted output
you'll need to use a different analyzer which will break the tokens on every ';' just for the category field rather than 'whitespaces'.
You should first ensure your Category data is populated as a Collection(Edm.String) in the index. See Supported Data Types in the official documentation. Each of your semicolon-separated values should be separate values in the collection, in a property called Category (or similar).
You can then filter by string values in the collection. See rules for filtering string collections. Assuming that your index contains a string collection field called Category, you can filter by categories containing Embedded like this:
Category/any(c: c eq 'Embedded')
You can filter by multiple values like this:
Category/any(c: search.in(c, 'Embedded, Automation'))
Start with clean data in your index using proper types for the data you have. This allows you to implement proper facets and you can utilize the syntax made specifically for this. Trying to work around this with wildcards is a hack that should be avoided.
To solve above mention problem used a below SQL function which will convert category to a json string array supported by Collection(Edm.String) data type in Azure Search.
Sql Function
CREATE FUNCTION dbo.GetCategoryAsArray
(
#ID VARCHAR(20)
)
RETURNS NVARCHAR(MAX)
AS
BEGIN
DECLARE #result NVARCHAR(MAX) = ''
SET #result = REPLACE(
STUFF(
(SELECT
','''+ TRIM(Value) + ''''
FROM dbo.TABLEA p
CROSS APPLY STRING_SPLIT (Category, ';')
WHERE p.ID = #ID
FOR XML PATH('')
),1,1,''),'&','&')
RETURN '[' + #result + ']'
END
GO
View to use function and return desired data
CREATE View dbo.TABLEA_VIEW AS
select
id
,dbo. GetCategoryAsArray(id) as CategoryArr
,type
,region
,Category
from dbo.TABLEA
Defined a new Azure Search Index using above SQL View as data source and during Index column mapping defined CategoryArr column as Collection(Edm.String) data type
Query to use to achieve expected output from Azure Search
$filter=Region eq 'AA' and CategoryArr/any(c: search.in(c, 'Embedded, Automation'))

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");

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

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.

Generate table in hubot brain and insert values

I'm trying to make a table of values inside hubot and he pass it's values to redis-brain.coffee but i just know a way: robot.brain.get("blablabla").
This will get a string from redis-brain and i need some kind of table.
How I'll use it:
At first call of this function, hubot will load the full database to the memory, then, if there's
robot.catchAll (msg) ->
if not quiet
text = msg.message.text
ector.setUser msg.message.user.name
if not loaded_brain
ector_brain = robot.brain.get('ector_brain') #need to be some type of table - In mysql should be like a select
ector.addEntry ector_brain
loaded_brain = true
else
ector.addEntry text
ector_brain = ector_brain+text #this line should insert the value of text inside ector_brain table. -- In mysql shoud be like an insert into
ector.linkNodesToLastSentence previousResponseNodes
response = ector.generateResponse()
previousResponseNodes = response.nodes
msg.reply response.sentence
So, how do I create a table in redis from hubot?
robot.brain.get and robot.brain.set operates with JSON objects, not only strings. Just place an object with your data structure of choice in the brain and get it back when necessary.

Subsonic 3: Strongly typed return value for stored procedures that return mixed results from different tables

Say I have a stored procedure that returns dataSet from 2 different tables. Example:
SELECT Customers.FirstName, Customers.LastName, SUM(Sales.SaleAmount) AS SalesPerCustomer
FROM Customers LEFT JOIN Sales
ON Customers.CustomerID = Sales.CustomerID
GROUP BY Customers.FirstName, Customers.LastName
Is there any way to get a strongly typed list as a result from this stored procedure ? Something like this:
StoredProcedure sp = myDevDB.GetCustomerSales();
List<MyCustomType> resultSet = sp.ExecuteTypedList<MyCustomType>();
How and where do I define the MyCustomType class ? How do I map its properties to the actual table columns ?
thanks,mehul
I solved it by creating a class (in the same place as all my other classes, but I didn't extend IActiveRecord, it's just a vanilla class).
Make sure the property names have exactly the same name and data type as the ones in the procedure, then call db.sproc(params).ExecuteTypedList().AsQueryable(); and it populated fine.

Resources