Dynamic Filter ASP.NET Boilerplate - asp.net-boilerplate

I have problem with Dynamic Filters in ASP.NET Boilerplate. Multi tenancy is off
Configuration.MultiTenancy.IsEnabled = false;
When I send query to DB #DynamicFilterParam_000003 should be 1 as every Tenant Id in DB but it has value of 0.I tried every method given in ASP.NET Boilerplate documentations to set this parameter to 1 but nothing works and I can't disable this filters.This is part of the query in SQL Server Profiler:
FROM [dbo].[AbpRoles] AS [Extent1]
WHERE ((([Extent1].[TenantId] IS NULL) AND (#DynamicFilterParam_000003 IS NULL))
OR (([Extent1].[TenantId] IS NOT NULL) AND (([Extent1].[TenantId] = #DynamicFilterParam_000003) OR
(([Extent1].[TenantId] IS NULL) AND (#DynamicFilterParam_000003 IS NULL)))) ) AND (([Extent1].[IsDeleted] = #DynamicFilterParam_000001) )
AND (3 = [Extent1].[Id])',
N'#DynamicFilterParam_000003 int,#DynamicFilterParam_000004 bit,#DynamicFilterParam_000001 bit,#DynamicFilterParam_000002 bit', #DynamicFilterParam_000003=0,#DynamicFilterParam_000004=NULL,#DynamicFilterParam_000001=0,#DynamicFilterParam_000002=NULL

Related

ASP.NET Core how to specify a SQL query

If i have a table as called "users" and i want give only a query for example to show user as have id > 1.
How to do that in ASP.NET Core.
in php you can do like that:
$sql = "SELECT * FROM users WHERE id='1';";
but how to do same with ASP.NET CORE.
Sorry for my bad English.
You can use the FromSqlRaw extension method to begin a LINQ query based on a raw SQL query. FromSqlRaw can only be used on query roots, that is directly on the DbSet<>.
Note:DbSet.FromSql prior to Entity Framework Core 3.0
For parameterized queries , you could refer to the below examples:
1)Format string
var author = db.Authors.FromSqlRaw("SELECT * From Authors Where AuthorId = {0}", id).FirstOrDefault();
2)Create DbParameter objects for the provider that you are using.
var p1 = new SqliteParameter("#Id", id); // parameter construction for SqLite
var author = db.Authors.FromSqlRaw($"SELECT * From Authors Where AuthorId = #Id", p1).FirstOrDefault();
Reference:
https://learn.microsoft.com/en-us/ef/core/querying/raw-sql
https://www.learnentityframeworkcore.com/raw-sql

ssrs ORA_01008:NOT ALL VALIABLE BOUNDED [duplicate]

I have come across an Oracle problem for which I have so far been unable to find the cause.
The query below works in Oracle SQL developer, but when running in .NET it throws:
ORA-01008: not all variables bound
I've tried:
Changing the Oracle data type for lot_priority (Varchar2 or int32).
Changing the .NET data type for lot_priority (string or int).
One bind variable name is used twice in the query. This is not a problem in my
other queries that use the same bound variable in more than one
location, but just to be sure I tried making the second instance its
own variable with a different :name and binding it separately.
Several different ways of binding the variables (see commented code;
also others).
Moving the bindByName() call around.
Replacing each bound variable with a literal. I've had two separate variables cause the problem (:lot_pri and :lot_priprc). There were some minor changes I can't remember between the two. Changing to literals made the query work, but they do need to work with binding.
Query and code follow. Variable names have been changed to protect the innocent:
SELECT rf.myrow floworder, rf.stage, rf.prss,
rf.pin instnum, rf.prid, r_history.rt, r_history.wt
FROM
(
SELECT sub2.myrow, sub2.stage, sub2.prss, sub2.pin, sub2.prid
FROM (
SELECT sub.myrow, sub.stage, sub.prss, sub.pin,
sub.prid, MAX(sub.target_rn) OVER (ORDER BY sub.myrow) target_row
,sub.hflag
FROM (
WITH floc AS
(
SELECT flow.prss, flow.seq_num
FROM rpf#mydblink flow
WHERE flow.parent_p = :lapp
AND flow.prss IN (
SELECT r_priprc.prss
FROM r_priprc#mydblink r_priprc
WHERE priprc = :lot_priprc
)
AND rownum = 1
)
SELECT row_number() OVER (ORDER BY pp.seq_num, rpf.seq_num) myrow,
rpf.stage, rpf.prss, rpf.pin,
rpf.itype, hflag,
CASE WHEN rpf.itype = 'SpecialValue'
THEN rpf.instruction
ELSE rpf.parent_p
END prid,
CASE WHEN rpf.prss = floc.prss
AND rpf.seq_num = floc.seq_num
THEN row_number() OVER (ORDER BY pp.seq_num, rpf.seq_num)
END target_rn
FROM floc, rpf#mydblink rpf
LEFT OUTER JOIN r_priprc#mydblink pp
ON (pp.prss = rpf.prss)
WHERE pp.priprc = :lot_priprc
ORDER BY pp.seq_num, rpf.seq_num
) sub
) sub2
WHERE sub2.myrow >= sub2.target_row
AND sub2.hflag = 'true'
) rf
LEFT OUTER JOIN r_history#mydblink r_history
ON (r_history.lt = :lt
AND r_history.pri = :lot_pri
AND r_history.stage = rf.stage
AND r_history.curp = rf.prid
)
ORDER BY myrow
public void runMyQuery(string lot_priprc, string lapp, string lt, int lot_pri) {
Dictionary<int, foo> bar = new Dictionary<int, foo>();
using(var con = new OracleConnection(connStr)) {
con.Open();
using(var cmd = new OracleCommand(sql.rtd_get_flow_for_lot, con)) { // Query stored in sql.resx
try {
cmd.BindByName = true;
cmd.Prepare();
cmd.Parameters.Add(new OracleParameter("lapp", OracleDbType.Varchar2)).Value = lapp;
cmd.Parameters.Add(new OracleParameter("lot_priprc", OracleDbType.Varchar2)).Value = lot_priprc;
cmd.Parameters.Add(new OracleParameter("lt", OracleDbType.Varchar2)).Value = lt;
// Also tried OracleDbType.Varchar2 below, and tried passing lot_pri as an integer
cmd.Parameters.Add(new OracleParameter("lot_pri", OracleDbType.Int32)).Value = lot_pri.ToString();
/*********** Also tried the following, more explicit code rather than the 4 lines above: **
OracleParameter param_lapp
= cmd.Parameters.Add(new OracleParameter("lapp", OracleDbType.Varchar2));
OracleParameter param_priprc
= cmd.Parameters.Add(new OracleParameter("lot_priprc", OracleDbType.Varchar2));
OracleParameter param_lt
= cmd.Parameters.Add(new OracleParameter("lt", OracleDbType.Varchar2));
OracleParameter param_lot_pri
= cmd.Parameters.Add(new OracleParameter("lot_pri", OracleDbType.Varchar2));
param_lapp.Value = lastProcedureStackProcedureId;
param_priprc.Value = lotPrimaryProcedure;
param_lt.Value = lotType;
param_lot_pri.Value = lotPriority.ToString();
//***************************************************************/
var reader = cmd.ExecuteReader();
while(reader.Read()) {
// Get values from table (Never reached)
}
}
catch(OracleException e) {
// ORA-01008: not all variables bound
}
}
}
Why is Oracle claiming that not all variables are bound?
I know this is an old question, but it hasn't been correctly addressed, so I'm answering it for others who may run into this problem.
By default Oracle's ODP.net binds variables by position, and treats each position as a new variable.
Treating each copy as a different variable and setting it's value multiple times is a workaround and a pain, as furman87 mentioned, and could lead to bugs, if you are trying to rewrite the query and move things around.
The correct way is to set the BindByName property of OracleCommand to true as below:
var cmd = new OracleCommand(cmdtxt, conn);
cmd.BindByName = true;
You could also create a new class to encapsulate OracleCommand setting the BindByName to true on instantiation, so you don't have to set the value each time. This is discussed in this post
I found how to run the query without error, but I hesitate to call it a "solution" without really understanding the underlying cause.
This more closely resembles the beginning of my actual query:
-- Comment
-- More comment
SELECT rf.flowrow, rf.stage, rf.process,
rf.instr instnum, rf.procedure_id, rtd_history.runtime, rtd_history.waittime
FROM
(
-- Comment at beginning of subquery
-- These two comment lines are the problem
SELECT sub2.flowrow, sub2.stage, sub2.process, sub2.instr, sub2.pid
FROM ( ...
The second set of comments above, at the beginning of the subquery, were the problem. When removed, the query executes. Other comments are fine.
This is not a matter of some rogue or missing newline causing the following line to be commented, because the following line is a SELECT. A missing select would yield a different error than "not all variables bound."
I asked around and found one co-worker who has run into this -- comments causing query failures -- several times.
Does anyone know how this can be the cause? It is my understanding that the very first thing a DBMS would do with comments is see if they contain hints, and if not, remove them during parsing. How can an ordinary comment containing no unusual characters (just letters and a period) cause an error? Bizarre.
You have two references to the :lot_priprc binding variable -- while it should require you to only set the variable's value once and bind it in both places, I've had problems where this didn't work and had to treat each copy as a different variable. A pain, but it worked.
On Charles' comment problem: to make things worse, let
:p1 = 'TRIALDEV'
via a Command Parameter, then execute
select T.table_name as NAME, COALESCE(C.comments, '===') as DESCRIPTION
from all_all_tables T
Inner Join all_tab_comments C on T.owner = C.owner and T.table_name = C.table_name
where Upper(T.owner)=:p1
order by T.table_name
558 line(s) affected. Processing time: 00:00:00.6535711
and when changing the literal string from === to ---
select T.table_name as NAME, COALESCE(C.comments, '---') as DESCRIPTION
[...from...same-as-above...]
ORA-01008: not all variables bound
Both statements execute fine in SQL Developer. The shortened code:
Using con = New OracleConnection(cs)
con.Open()
Using cmd = con.CreateCommand()
cmd.CommandText = cmdText
cmd.Parameters.Add(pn, OracleDbType.NVarchar2, 250).Value = p
Dim tbl = New DataTable
Dim da = New OracleDataAdapter(cmd)
da.Fill(tbl)
Return tbl
End Using
End Using
using Oracle.ManagedDataAccess.dll Version 4.121.2.0 with the default settings in VS2015 on the .Net 4.61 platform.
So somewhere in the call chain, there might be a parser that is a bit too aggressively looking for one-line-comments started by -- in the commandText. But even if this would be true, the error message "not all variables bound" is at least misleading.
The solution in my situation was similar answer to Charles Burns; and the problem was related to SQL code comments.
I was building (or updating, rather) an already-functioning SSRS report with Oracle datasource. I added some more parameters to the report, tested it in Visual Studio, it works great, so I deployed it to the report server, and then when the report is executed the report on the server I got the error message:
"ORA-01008: not all variables bound"
I tried quite a few different things (TNSNames.ora file installed on the server, Removed single line comments, Validate dataset query mapping). What it came down to was I had to remove a comment block directly after the WHERE keyword. The error message was resolved after moving the comment block after the WHERE CLAUSE conditions. I have other comments in the code also. It was just the one after the WHERE keyword causing the error.
SQL with error: "ORA-01008: not all variables bound"...
WHERE
/*
OHH.SHIP_DATE BETWEEN TO_DATE('10/1/2018', 'MM/DD/YYYY') AND TO_DATE('10/31/2018', 'MM/DD/YYYY')
AND OHH.STATUS_CODE<>'DL'
AND OHH.BILL_COMP_CODE=100
AND OHH.MASTER_ORDER_NBR IS NULL
*/
OHH.SHIP_DATE BETWEEN :paramStartDate AND :paramEndDate
AND OHH.STATUS_CODE<>'DL'
AND OHH.BILL_COMP_CODE IN (:paramCompany)
AND LOAD.DEPART_FROM_WHSE_CODE IN (:paramWarehouse)
AND OHH.MASTER_ORDER_NBR IS NULL
AND LOAD.CLASS_CODE IN (:paramClassCode)
AND CUST.CUST_CODE || '-' || CUST.CUST_SHIPTO_CODE IN (:paramShipto)
SQL executes successfully on the report server...
WHERE
OHH.SHIP_DATE BETWEEN :paramStartDate AND :paramEndDate
AND OHH.STATUS_CODE<>'DL'
AND OHH.BILL_COMP_CODE IN (:paramCompany)
AND LOAD.DEPART_FROM_WHSE_CODE IN (:paramWarehouse)
AND OHH.MASTER_ORDER_NBR IS NULL
AND LOAD.CLASS_CODE IN (:paramClassCode)
AND CUST.CUST_CODE || '-' || CUST.CUST_SHIPTO_CODE IN (:paramShipto)
/*
OHH.SHIP_DATE BETWEEN TO_DATE('10/1/2018', 'MM/DD/YYYY') AND TO_DATE('10/31/2018', 'MM/DD/YYYY')
AND OHH.STATUS_CODE<>'DL'
AND OHH.BILL_COMP_CODE=100
AND OHH.MASTER_ORDER_NBR IS NULL
*/
Here is what the dataset parameter mapping screen looks like.
It's a bug in Managed ODP.net - 'Bug 21113901 : MANAGED ODP.NET RAISE ORA-1008 USING SINGLE QUOTED CONST + BIND VAR IN SELECT' fixed in patch 23530387 superseded by patch 24591642
Came here looking for help as got same error running a statement listed below while going through a Udemy course:
INSERT INTO departments (department_id, department_name)
values( &dpet_id, '&dname');
I'd been able to run statements with substitution variables before. Comment by Charles Burns about possibility of server reaching some threshold while recreating the variables prompted me to log out and restart the SQL Developer. The statement ran fine after logging back in.
Thought I'd share for anyone else venturing here with a limited scope issue as mine.
I'd a similar problem in a legacy application, but de "--" was string parameter.
Ex.:
Dim cmd As New OracleCommand("INSERT INTO USER (name, address, photo) VALUES ('User1', '--', :photo)", oracleConnection)
Dim fs As IO.FileStream = New IO.FileStream("c:\img.jpg", IO.FileMode.Open)
Dim br As New IO.BinaryReader(fs)
cmd.Parameters.Add(New OracleParameter("photo", OracleDbType.Blob)).Value = br.ReadBytes(fs.Length)
cmd.ExecuteNonQuery() 'here throws ORA-01008
Changing address parameter value '--' to '00' or other thing, works.

Optimize Linq query with PredicateBuilder with N-N join

I'm using Linq to query MS CRM 2011 Web Services. I've got a query that results in very poor SQL, it fetches too much intermediary data and its performance is horrible!! I'm new to it, so it may very well be the way I'm using it...
I've got two entities linked via an N-N relationship: Product and SalesLink. I want to recover a bunch of Product from their SerialNumber along with all SalesLink associated to them.
This is the query I have using PredicateBuilder:
// Build inner OR predicate on Serial Number list
var innerPredicate = PredicateBuilder.False<Xrm.c_product>();
foreach (string sn in serialNumbers) {
string temp = sn; // This temp assignement is important!
innerPredicate = innerPredicate.Or(p => p.c_SerialNumber == temp);
}
// Combine predicate with outer AND predicate
var predicate = PredicateBuilder.True<Xrm.c_product>();
predicate = predicate.And(innerPredicate);
predicate = predicate.And(p => p.statecode == (int)CrmStateValueType.Active);
// Inner Join Query
var prodAndLinks = from p in orgContext.CreateQuery<Xrm.c_product>().AsExpandable()
.Where(predicate)
.AsEnumerable()
join link in orgContext.CreateQuery<Xrm.c_saleslink>()
on p.Id equals link.c_ProductSalesLinkId.Id
where link.statecode == (int)CrmStateValueType.Active
select new {
productId = p.Id
, productSerialNumber = p.c_SerialNumber
, accountId = link.c_Account.Id
, accountName = link.c_Account.Name
};
...
Using SQL profiler, I saw that it causes an intermediate SQL query that has no WHERE clause, looking like this:
select
top 5001 "c_saleslink0".statecode as "statecode"
...
, "c_saleslink0".ModifiedOnBehalfByName as "modifiedonbehalfbyname"
, "c_saleslink0".ModifiedOnBehalfByYomiName as "modifiedonbehalfbyyominame"
from
c_saleslink as "c_saleslink0" order by
"c_saleslink0".c_saleslinkId asc
This returns a huge amount of (useless) data. I think the join is done on the client side instead of on the DB side...
How should I improve this query? I runs in around 3 minutes and that's totally unacceptable.
Thanks.
"Solution"
Based on Daryl's answer to use QueryExpression instead of Linq to CRM, I got this which gets the exact same result.
var qe = new QueryExpression("c_product");
qe.ColumnSet = new ColumnSet("c_serialnumber");
var filter = qe.Criteria.AddFilter(LogicalOperator.Or);
filter.AddCondition("c_serialnumber", ConditionOperator.In, serialNumbers.ToArray());
var link = qe.AddLink("c_saleslink", "c_productid", "c_productsaleslinkid");
link.LinkCriteria.AddCondition("statecode", ConditionOperator.Equal, (int)CrmStateValueType.Active);
link.Columns.AddColumns("c_account");
var entities = serviceProxy.RetrieveMultiple(qe).Entities.ToList();;
var prodAndLinks = entities.Select(x => x.ToEntity<Xrm.c_product>()).Select(x =>
new {
productId = x.c_productId
, productSerialNumber = x.c_SerialNumber
, accountId = ((Microsoft.Xrm.Sdk.EntityReference)((Microsoft.Xrm.Sdk.AliasedValue)x["c_saleslink1.c_account"]).Value).Id
, accountName = ((Microsoft.Xrm.Sdk.EntityReference)((Microsoft.Xrm.Sdk.AliasedValue)x["c_saleslink1.c_account"]).Value).Name
}).ToList();
I really would have liked to find a solution using Linq, but it seems to Linq to CRM is just not there yet...
95% of the time when you're having performance issues with a complicated query in CRM, the easiest way to improve the performance is to run a straight SQL query against the database (assuming this is not CRM online of course). This may be one of the 5% of the time.
In your case, the major performance issue you're experiencing is due to the predicate builder forcing a CRM Server (not the SQL database) side join of data. If you used a Query Expression (which is what your link statement get's translated) you can specify a Condition Expression with an IN operator that would allow you to pass in your serialNumbers collection. You could also use FetchXml as well. Both of these methods would allow CRM to perform a SQL side join.
Edit:
This should get you 80% of the way with Query Expressions:
IOrganizationService service = GetService();
var qe = new QueryExpression("c_product");
var filter = qe.Criteria.AddFilter(LogicalOperator.Or);
filter.AddCondition("c_serialnumber", ConditionOperator.In, serialNumbers.ToArray());
var link = qe.AddLink("c_saleslink", "c_productid", "c_productsaleslinkid");
link.LinkCriteria.AddCondition("statecode", ConditionOperator.Equal, (int)CrmStateValueType.Active);
link.Columns.AddColumns("c_Account");
var entities = service.RetrieveMultiple(qe).Entities.ToList();
You will probably find you can get better control by not using Linq to Crm. You could try:
FetchXml, this is an xml syntax, similar in approach to tsql MSDN.
QueryExpression, MSDN.
You could issue a RetrieveRequest, blog.

2 ways to get the latest row from db

I have a struts2 app with spring transactions and JPA2 over hibernate. The problem is that I have some rows in the database that are changed by an external source (some mysql triggers) and in my front app I have an ajax script that checks this values every 2 seconds. I always need to get the latest value, and not a cached one, and for this I found 2 solutions :
String sql = "FROM MyEntity WHERE xId=:id AND connect!=0 AND complete=0 AND (error=NULL OR error=0)";
Query q = this.em.createQuery(sql).setHint("org.hibernate.cacheable", false).setParameter("agId", agentId);
rs = q.getResultList();
if(rs.size() == 1){
intermedObj = (Intermed) rs.get(0);
}
and the other:
String sql = "FROM MyEntity WHERE xxId=:id AND connect!=0 AND complete=0 AND (error=NULL OR error=0)";
Query q = this.em.createQuery(sql).setParameter("agId", agentId);
rs = q.getResultList();
if(rs.size() == 1){
intermedObj = (Intermed) rs.get(0);
//get latest object from DB
em.refresh(intermedObj);
}
em is a instance of EntityManager which is managed by spring.
So, the question is: which is the best approach from these 2? Or maybe there is a better one ?
So you are right, I used hql there, I still have to learn a lot about hibernate an jpa, and java in general. So I guess that the correct way to write that cod in JPQL would be:
String sql = "SELECT m FROM MyEntity m WHERE m.xxId=:id AND m.connect!=0 AND m.complete=0 AND (m.error!=1)";
Query q = this.em.createQuery(sql).setParameter("agId", agentId);
rs = q.getResultList();
if(rs.size() == 1){
intermedObj = (Intermed) rs.get(0);
//get latest object from DB
em.refresh(intermedObj);
}
So the question would be, is this the proper way to make sure that I got the latest row from DB and not a cached record?
As regarding leve2 cache question I do not know if this is activated. How do I check that?

Insert using linq templates not returning the id - MySQL

I'm using the latest subsonic dll and the latest linq templates from github. The db i'm inserting into is MySQL. Id column on table is primary key auto increment.
Versions:
Subsonic.Core.dll - 3.0.0.3 - (November 18, 2009 Merged pulls from Github).
LinqTemplates - July 29, 2009.
MySQL.Data.CF.dll - 6.1.2.0.
The row is inserted but the id is returned as 0.
Example of the insert:
mysqldb db = new mysqldb.mysqldbDB();
int ID = db.Insert.Into<db.myTable>(
r => r.message,
r => r.name,
r => r.status).Values(
message,
name,
status).Execute();
Am I doing something wrong? Shouldn't the new id be returned, not zero?
Found the bug in subsonic core.
It's in Subsonic.Core.Query.Insert.cs
The Execute method does not have a condition for id's returned that are of type long.
I've rewritten the method in my local version to:
public int Execute()
{
int returner = 0;
object result = _provider.ExecuteScalar(GetCommand());
if(result != null)
{
if(result.GetType() == typeof(decimal))
returner = Convert.ToInt32(result);
else if (result.GetType() == typeof(int))
returner = Convert.ToInt32(result);
else if (result.GetType() == typeof(long))
returner = Convert.ToInt32(result);
else
returner = Convert.ToInt32(result);
}
return returner;
}
I've changed the multiple if statements to else if's and added the type comparison of long. Also I've added the final else condition which does a convert to int. Not sure if that's such a good idea but it works for me.
If someone wants to update the source great. If i find time sometime soon i'll update it myself.