Sort a LINQ with another LINQ in MVC - sql-server

Using SQL Server Management
Using MVC VS 2013 for Web
Being in a Controller
Here materialnumb it's a LINQ query that always return only one value.
Being the following...
var materialnumb = (from r in db.MaterialNumber
where r.MaterialNumber == 80254842
select r.MaterialNumber);
I have another LINQ query from a SQL view that involves several other tables with inner join statements and so on (which includes the previous table db.MaterialNumber) that goes like this:
var query = (from r in db.SQLViewFinalTable
where r.MaterialNumber == Convert.ToInt32(materialnumb.MaterialNumber)
select r
I want to sort all the materials by the retrieved material number from the first query but it drops the following error when I try to pass the query as a model for my View:
LINQ to Entities does not recognize the method 'Int32
ToInt32(System.String)' method, and this method cannot be translated
into a store expression.
I assume this is because the query is an object even if its has just one value so it can't be converted into a single Int32.
Even more, the query it's not being executed, it's just a query...
So, how can achieve my goal?
Additional information: I tried to convert the query outside the "final" query. It still doesn't work.
Additional information: This is just an example, the true query actually has several more other querys embedded and this other querys have also other querys in them, so I need a practical way.
Additional information: I have also tried to convert the query into a string and then again into an int.

Try this:
var materialnumb = (from r in db.MaterialNumber
where r.MaterialNumber == 80254842
select r.MaterialNumber).FirstOrDefault();
var query = from r in db.SQLViewFinalTable
where r.MaterialNumber == materialnumb
select r
But I can not get whay are you filtering by 80254842 and selecting the same value? You can do directly:
var query = from r in db.SQLViewFinalTable
where r.MaterialNumber == 80254842
select r

Related

Using SqlKata from an existing Query

I have existing queries used for jobs that run within services to generate reports. Simple things like
"Select * from Transactions"
The jobs will then append parameters to these queries based on preset rules, like Date>Yesterday etc. SqlKata looks like it can do this but I'm not sure how to instantiate the Query object from an existing query. Is something like this possible?
Dim Qry as new Query("Select * from Transactions").OrderByDesc("Date")
Qry.Where("Date", ">", Date.Now().AddDays(-1))
return Qry.Get()
The closest thing that you can do in this case is to wrap the inner query and add conditions on top of it, you can use the SubQuery or CTE approach here.
Something like this, this in C# but the idea is the same.
var existingSql = "select * from transactions";
var query = new Query().FromRaw($"({existingSql}) as inner")
.Where("date", ">=", DateTime.UtcNow.Date);
checkout this example on playground

PostgreSQL query not working in Yii2

I want to execute query in my yii2 application. I'm using PostgreSQl. There is a table called list inside the user schema. If I try to build any query it returns 1. My code is here:
$numUsers = Yii::$app->db->createCommand('
SELECT COUNT(*) FROM "user"."list"
')->execute();
Please show me my mistake in the query above.
This is not related to the DB type in Yii2 if you want the result of a single value you should use queryScalar() instead of execute()
$numUsers = Yii::$app->db->createCommand('
SELECT COUNT(*) FROM "user"."list" ')->queryScalar();

SQL Server - Getting XML from result set within one tag

I am trying without much success to build a XML out of my result set.
My result set should look like this :
<CSVRoot>
<CsvColumn>MDCY_Code</CsvColumn>
<CsvColumn>MDCY_Description</CsvColumn>
</CSVRoot>
This is what my query returns :
<CSVRoot>
<CSVHeader>
<CsvColumn>MDCY_Code</CsvColumn>
</CSVHeader>
<CSVHeader>
<CsvColumn>MDCY_Description</CsvColumn>
</CSVHeader>
</CSVRoot>
I know that I can use flowr on this formed XML and remake the XML, but that's additional processing. Is there any way to do this without further processing ( such as using a flowr to form a new XML ) in one query?
This is what I've used:
select
utma.CsvColumn as [ColumnName]
from
Methods m
inner join
UITestMap utm on m.UITestMapID = utm.ID
inner join
SubMethods sm on m.Id = sm.HeaderID
inner join
UITestMapActions utma on sm.UITestMapActionID = utma.ID
for xml path('CSVHeader'),root('CSVRoot')
Edit 2 :
This isn't working, I get the same output.Utma has one column that I need in my query and that is CSVColumn.
Edit 3:
Now I'm getting this :
<CsvHeader>
<ColumnName>MDCY_Cod</ColumnName>
<ColumnName>MDCY_Descriere</ColumnName>
</CsvHeader>
Which is the correct answer.
I wasn't sure how I wanted to process the result sets, actually I will need to use flowr to create a new xml out of this output. ( which is what I needed in the first place)
Try this:
select
utma.CsvColumn
from
Methods m
for xml path(''),root('CSVRoot')

Entity Framework Query Cache bloat on SQL Server database

I currently have an issue in that there are thousands of plans created on the DB for 1 style of EF query.
The query itself is parametrized, but the parameter name keeps changing and hence the text is different, and so results in a fresh new compile for each query hitting my DB server.
So the query looks like this.
(#p__linq__100687 int)SELECT [Extent1].[MyColumn] From MyTable [Extent1]
Where Column1 = #p__linq__100687
and the next one looks like this
(#p__linq__100688 int)SELECT [Extent1].[MyColumn] From MyTable [Extent1]
Where Column1 = #p__linq__100688
What I would like EF to do is
(#p__linq__1 int)SELECT [Extent1].[MyColumn] From MyTable [Extent1]
Where Column1 = #p__linq__1
And then keep reusing the query above instead of incrementing and then being
forced to create a new plan.
So when I trawl through the plan cache on the DB I get a total of 7GB of plans which have only been used once.
I am a DBA and need to figure out what to tell the Vendor Devs since they are adamant that this is the correct way to implement EF as per MS.
I have searched google and asked a couple of dev friends around the construction of the code in the background but the answer still eludes.
I just did some tests using VS 2017 and EF 6 and had no problem with this, even trying some bad c# codes.
I tried this:
AdventureWorks2016Entities ctx = new AdventureWorks2016Entities();
for (var i = 1; i <= 50; i++)
{
var query = (from x in ctx.bigProduct.AsNoTracking()
where x.ReorderPoint == i
select x);
var result = query.ToList();
}
and this :
for (var i = 1; i <= 50; i++)
{
AdventureWorks2016Entities ctx = new AdventureWorks2016Entities();
var query = (from x in ctx.bigProduct.AsNoTracking()
where x.ReorderPoint == i
select x);
var result = query.ToList();
}
The first code block is re-creating the query in each iteration and the 2nd code block is also re-creating the context in each iteration. None of these options created the plan cache bloat you are suffering.
What's the EF version your application is using ?
However, I found this problem with the decimal type in EF. I just posted a question about this, you can find it here - How to avoid plan cache bloat using queries in entity framework

Choosing SQL join types for Entity Framework 4

I have a query for example:
var personList = context.People;
People is a view that has 2 joins on it and about 2500 rows and takes ~10 seconds to execute.
Looking at the Estimated Execution plan tells me that it is using a nested loop.
Now if i do this:
var personList = context.People.Where(r => r.Surname.Length > -1);
Execution time is under a second and the execution plan is using a Hash Join.
Adding "OPTION (HASH JOIN)" to the generated SQL has the desired effect of increasing performance.
So my question is ...
How can i get the query to use a Hash Join? It can't be added to the view (I tried, it errors).
Is there an option in EF4 that will force this? Or will i have to put it in a stored procedure?
RE: View
SELECT dbo.DecisionResults.ID, dbo.DecisionResults.UserID, dbo.DecisionResults.HasAgreed, dbo.DecisionResults.Comment,
dbo.DecisionResults.DateResponded, Person_1.Forename, Person_1.Surname, Site_1.Name, ISNULL(dbo.DecisionResults.StaffID, - 999)
AS StaffID
FROM dbo.DecisionResults INNER JOIN
Server2.DB2.dbo.Person AS Person_1 ON Person_1.StaffID = dbo.DecisionResults.StaffID INNER JOIN
Server2.DB2.dbo.Site AS Site_1 ON Person_1.SiteID = Site_1.SiteID
ORDER BY Person_1.Surname
If i add OPTION(HASH JOIN) to the end it will error with :
'Query hints' cannot be used in this query type.
But running that script as a query works fine.

Resources