I am trying to create an update query in SQLKata that includes a 'FromRaw' statement. Below is a copy of my best attempt at what I am trying to accomplish. I have to use a FromRaw statement because I am linking 2 tables on an evaluation. Is there any way to accomplish this without having to resort to the Statement() function?
var query = db.Query(Table1)
.FromRaw(" Table1 INNER JOIN Table2 " +
" ON LEFT([Table1].[Company],5) = " +
" LEFT([Table2].[Company],5)" )
.Update(new { scrub = "match" });
Below is a copy of the error message:
System.InvalidOperationException: 'Invalid table expression'
This bit of code works just fine for me:
var compiler = new SqlServerCompiler();
//var Table1 = "Table1";
var query = new Query(null)
.FromRaw("Table1 INNER JOIN Table2 " +
"ON LEFT([Table1].[Company],5) = " +
"LEFT([Table2].[Company],5)")
.AsUpdate(new { scrub = "match" });
var rawSql = compiler.Compile(query).RawSql;
With rawSql value being:
UPDATE Table1 INNER JOIN Table2 ON LEFT([Table1].[Company],5) = LEFT([Table2].[Company],5) SET [scrub] = ?
The error message you're getting is only found in Compiler.cs, which is why I suggested that you check which compiler you're using.
Related
var db = new SQLiteConnection(dbPath);
try
{
var results = db.Query<Xclass>("SELECT X.COL1, X.COL2, " +
" X.COL3, X.Col4, X.Col5, " +
" A.Col2, A.COL3, B.Col2, C.Col2 " +
"FROM left join Xam X " +
"left join TABLE1 A on X.COL1 = A.COL1 " +
"left join TABLE2 B on X.COL2 = B.COL1 " +
"left join TABLE3 C on X.COL3 = C.COL1 " +
"WHERE X.COL1 ='"+ somevalue +"'");
}
catch (Exception e)
{
// display message
}
XCLASS Contains all the getters and setters.
But it only pulls in the Xam table and not the A, B, or C table values.
I originally had the table name in the Class but took it out to see if that would help.
Any assistance is appreciated. I am trying to avoid linq but if is necessary I will try it.
The instance(s) of Xclass object is created from the results of your query via reflection.
The columns in query's result set are translated to properties of the class
and the setters of hese properties are used to assign their values.
Therefore you must supply some hints to SQlite so it will know which column corresponds to which property. This is done via as keyword.
So, if you want assign the value of A.COL2 column in the result to property named MyCol2Property inside Xclass, you must retrieve it in the query using the syntax
A.Col2 as MyCol2Property
When using the following SQL-statement within c#/OleDbCommand.ExecuteReader I get a syntax error in FROM-clause.
Using exactly the same statement in MS Access directly works fine.
SELECT
s.idShots, s.shotdata, c.[original], s.[hash], comp.idCompetitions, comp.competitionsname, sh.idShooters, sh.firstname, sh.lastname
FROM (([Shots] s
INNER JOIN [ShotsCertificate] c ON c.[uuid] = s.[uuid])
INNER JOIN [Competitions] comp ON comp.idCompetitions = s.fidCompetitions)
INNER JOIN [Shooters] sh ON sh.idShooters = s.fidShooters ORDER BY s.idShots ASC
Within c#:
OleDbCommand cmd2 = new OleDbCommand("", dbc);
cmd2.CommandText = "SELECT s.idShots, s.shotdata, c.[original], s.[hash], comp.idCompetitions, comp.competitionsname, sh.idShooters, sh.firstname, sh.lastname FROM" +
" (([Shots] s" +
" INNER JOIN [ShotsCertificate] c ON c.[uuid] = s.[uuid])" +
" INNER JOIN [Competitions] comp ON comp.idCompetitions = s.fidCompetitions)" +
" INNER JOIN [Shooters] sh ON sh.idShooters = s.fidShooters" +
" ORDER BY s.idShots ASC";
log.Debug(cmd2.CommandText);
OleDbDataReader r = cmd2.ExecuteReader();
The dbc connections works fine, it's used in some previous commands and everything works.
Thanks for your suggestions!
For the record, the issue was that COMP is included in the list of Access SQL Reserved Words, presumably as an abbreviation of COMPRESSION for Access DDL. Changing the table alias from comp to cmpt allowed the query to run successfully under System.Data.OleDb:
sql = "SELECT s.idShots, s.shotdata, c.[original], s.[hash], cmpt.idCompetitions, cmpt.competitionsname, sh.idShooters, sh.firstname, sh.lastname FROM" +
" (([Shots] s" +
" INNER JOIN [ShotsCertificate] c ON c.[uuid] = s.[uuid])" +
" INNER JOIN [Competitions] cmpt ON cmpt.idCompetitions = s.fidCompetitions)" +
" INNER JOIN [Shooters] sh ON sh.idShooters = s.fidShooters" +
" ORDER BY s.idShots ASC";
I got it working ... no comment :/
SELECT
[Shots].[idShots], [Shots].[shotdata], [ShotsCertificate].[original], [Shots].[hash], [Competitions].[idCompetitions], [Competitions].[competitionsname], [Shooters].[idShooters], [Shooters].[firstname], [Shooters].[lastname]
FROM (([Shots]
INNER JOIN [ShotsCertificate] ON [ShotsCertificate].[uuid] = [Shots].[uuid])
INNER JOIN [Competitions] ON [Competitions].[idCompetitions] = [Shots].[fidCompetitions])
INNER JOIN [Shooters] ON [Shooters].[idShooters] = [Shots].[fidShooters]
ORDER BY [Shots].[idShots] ASC
I am trying to execute a raw query using c#.
Here is what I have done
var accounts = conn.Database.SqlQuery<IEnumerable<string>>("SELECT TOP 1 a.* FROM zipcodes_to_accounts AS c " +
"INNER JOIN accounts AS a ON a.id = c.account_id " +
"WHERE c.zip_code = #p0 "+
"ORDER BY a.completed_ll + a.completed_cp ASC", zipcode).ToArray();
Then I want to take the first record and convert it to json object.
if (accounts.Count() > 0)
{
return JsonConvert.SerializeObject( accounts.First() );
}
But the query is giving me an error
The result type 'System.Collections.Generic.IEnumerable`1[System.String]' may not be abstract and must include a default constructor.
The accounts table has some columns that are varchar, datetime, integers. How can I get this query to work?
UPDATED
Converting the IEnumerable to list like advised in the answer it working. but now the JsonConvert is returning an empty object. Here is my current code
//getAccount
public string GetAccount()
{
string zipcode = StringHelpers.StringOrNull(Request["zip_code"]);
if (zipcode != null)
{
var accounts = conn.Database.SqlQuery<List<string>>("SELECT TOP 1 a.* FROM zipcodes_to_accounts AS c " +
"INNER JOIN accounts AS a ON a.id = c.account_id "+
"WHERE c.zip_code = #p0 "+
"ORDER BY a.completed_ll + a.completed_cp ASC", zipcode).ToList();
var firstAccount = accounts.FirstOrDefault();
if (firstAccount != null)
{
return JsonConvert.SerializeObject(firstAccount);
}
}
return "{}";
}
When I debug my code Here is what I see
Not sure what ORM you're using, but the warning is telling you that IEnumerable cannot be constructed as it's an interface. Therefore the SqlQuery method can't know what return type you're expecting.
Try replacing the generic constraint with a concrete type:
var accounts = conn.Database.SqlQuery<string>("SELECT TOP 1 a.* FROM zipcodes_to_accounts AS c " +
"INNER JOIN accounts AS a ON a.id = c.account_id " +
"WHERE c.zip_code = #p0 "+
"ORDER BY a.completed_ll + a.completed_cp ASC", zipcode).ToArray();
You're asking for a IEnumerable<string> which is an interface. You need to pick a class that implements IEnumerable such as a List
I was trying to replace SQL code with LINQ in order to migrate in to MVC ,but i don't know how to use subquery in LINQ.As of now i have replaced inner sql query with LINQ,i would like to know how to do with outer query.
Following is the SQL query
SELECT
DISTINCT GP_REGION.REGION_MAIN Region_Code,
R1.REGION_NAME
FROM
GP_REGION
INNER JOIN GP_REGION R1 ON GP_REGION.REGION_MAIN = R1.REGION_CODE
WHERE
GP_REGION.REGION_HAS_DATA = 'Y'
AND
GP_REGION.REGION_MAIN IN
(
SELECT
DISTINCT AR.BRANCH_CODE
FROM
PORTAL.UA_APPLN_ROLE AR
INNER JOIN PORTAL.UA_GROUP G ON AR.GROUP_CODE = G.GROUP_CODE
WHERE
G.USER_ID = '" + Global.UserId() + "' AND AR.APPLICATION_ID = '" + ApplicationId + "'
)
ORDER BY
GP_REGION.REGION_MAIN
Here the inner query i have replaced as shown below by using following LINQ
var regions = from p in db3.UA_APPLN_ROLE.AsEnumerable()
join i in db3.UA_GROUP.AsEnumerable()
on p.GROUP_CODE equals i.GROUP_CODE
where
i.USER_ID == Global.UserId()
&&
p.APPLICATION_ID == ConfigurationManager.AppSettings["ApplicationId"]
select new
{
branchcode = p.BRANCH_CODE
};
But i would like to know the outer sql query how can i replace and join with existing LINQ code i wrote
You combine the subquery into the main query as follows:
var efQuery = from gp in db3.GP_REGION
join r1 in db3.GP_REGION on gp.REGION_MAIN equals r1.REGION_CODE
where regions.Contains(gp.REGION_MAIN)
&& gp.REGION_HAS_DATA = "Y"
select new
{
Region_Code = gp.REGION_MAIN,
Region_Name = r1.REGION_NAME
};
var queryResult = efQuery.Distinct().OrderBy(x => x.Region_Code);
You can speed the processing up a bit by using .AsNoTracking(), e.g. db3.GP_REGION.AsNoTracking().
In general it's a good idea to monitor the generated SQL query to avoid situations where it looks simple in code, but is transformed into bad SQL.
But in my opinion the advantages of having the query a first class member in your code (compared to SQL in strings) outweigh the sometimes non-intuitive generated SQL.
I use Sql Server compact database, and my linq query work properly in debug mode, but it has error in release mode !
My query use "join" and the exception is:
The method '
[My_Project_Namespace.MyTransactions,My_Project_Namespace.Users].
' is not a property accessor
Here is my LINQ query:
var result = from transRow in db.MyTransactions
join userRow in db.Users on transRow.User_id equals userRow.Id
join clientRow in db.Clients on
transRow.Client_id equals clientRow.Id
select new
{
userId = transRow.User_id,
clientId = transRow.Client_id,
userName = userRow.Fname + " " + userRow.Lname,
clientName = clientRow.Fname + " " + clientRow.Lname,
reg_date = transRow.Reg_date,
value = transRow.Value
};
My aim is add (or replace) the user id with his name and also the client id with his name.
as Oleksiy Gapotchenko (Eazfuscator.NET Developer) said here
you need to add this on the assembly level:
[assembly: Obfuscation(Feature = "anonymous type properties renaming", Exclude = true)]
then, all of your anonymous method and types won't be obfuscated, and (probably) will work....
I found out that's because of using some obfuscators like "Eazfuscator.NET".
but it will work with some other obfuscators like "Babel" !