Linq/Entity Framework, performing xpath query on column - c#

We have a database that contains xml fields. At this moment we perform queries on this database that filter on values in the xml. In the near future we would like to migrate to entity framework or NHibernate as orm. Is this possible? This are two of the queries we run (in sql):
SELECT
yy.[Description] as Name,
convert(xml, yy.Xml).value('(//Division)[1]', 'varchar(255)') as Division,
onvert(xml, yy.Xml).value('(//Season)[1]', 'varchar(255)') as Season
into #Statistics .....
And
SELECT [dbo].[yy].[Id]
FROM [dbo].[yy]
WHERE [dbo].[yy].[ApplicationId] = 1
AND (((dbo.[yy].Xml.exist(''(//qq[Season='Non seasonal'])'') = 1)))
Is there anyway to do this?

In EF there are a variety of ways to pass SQL directly through to the server, e.g. ObjectContext.ExecuteStoreQuery. You could also write a stored proc which does the xpath query and map that as usual. There is no native support for xpath in LINQ or Entity SQL, as far as I know.

Related

Alternative to LINQ RemoveRange in EF 6

I have two tables, Transactions and TransactionsStaging.
I am using a LINQ query to fetch all rows in TransactionsStaging which have a duplicate in Trasactions and then removing them form TranscationsStaging. So ultimately I am removing all entries in TransactionsStaging which have a duplicate in Transactions table.
I have produced the following so far:
IEnumerable<WebApi.Models.TransactionStaging> result = (from ts in db.TransactionsStaging
join t in db.Transactions
on ts.Description equals t.Description
select ts).ToList();
db.TransactionsStaging.RemoveRange(result);
db.SaveChanges();
The above works, but when inspecting the actual SQL queries being sent to the DB, I noticed that the RemoveRange produces a SQL DELETE statement for each row it is removing.
Is there a way to accomplish the same but avoid the multiple delete statements?
I wanted to explore this possibility before switching to executing a raw SQL statement rather than using Linq and ORM.
If you want to issue only a single database command, either a stored proc or raw SQL statements would be the way to go, since EntityFramework does not support bulk transactions.
You could go with a variety of bulk extensions available for batch operations.

How To can Select**DB Table

If I have a database in each table where the ID field and its appropriate function in any field do not take the administrator behavior so that tables and field contents can be fetched until the serial number is unified without duplicate values
Appropriate in this context using except.
Is there a code that can fetch tables either in sql or in the Entity Framework ؟
Eexcept_Admin_except_List
List<int> tempIdList = answeripE.Select(q => q.ID).ToList();
var quslist = db.Qustion.Where(q => !tempIdList.Contains(q.ID));
\Thanks for the creator of "daryal" Get All Except from SQL database using Entity Framework
I need to do this without asking for each table and querying it. And also request SQL from the database as a whole without exception such as
select*
IDfield
FROM
MSDB_Table T
WHERE
T.id == MaxBy(T.OrderBy(x => x.id);
can replace "where TABLE1.id 'OR' Table2.id" decode all the tables and give a result.
All I'm looking forward to is that I can query one database on a whole, get it on a list without the use of tables or a composite key because it serves me in analyzing a set of data converted to other data formats, for example when representing a database in the form of JSON There are a lot of them on more than one platform and in a single database and to avoid the repetition of the data I need to do this or a comprehensive query may be compared or to investigate or like Solver Tool in Excel, so far did not get the answer to show me the first step is because it does not exist originally or because it is not possible?
If you want Entity Framework to retrieve all columns except a subset of them, the best way to do that is either via a stored procedure or a view. With a view you can query it using LINQ and add your predicates in code, but in a stored procedure you will have to write it and feed your predicate conditions into it...so it sounds like a view would be better for you.
Old example, but should guide you through the process:
https://www.mssqltips.com/sqlservertip/1990/how-to-use-sql-server-views-with-the-entity-framework/

SQL equivalent of Count extension method for LINQ isn't obvious

I'm doing LINQ to entity framework (EF) to get count of records in my table using below code:
using (var db = new StackOverflowEntities())
{
var empLevelCount = db.employeeLevels.Count();
}
I captured the query fired by EF towards database using SQL Server Profiler. I got the following query :
SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
COUNT(1) AS [A1]
FROM [dbo].[employeeLevels] AS [Extent1]
) AS [GroupBy1]
This query remains exactly the same even for LongCount extension method except for the fact that COUNT SQL function gets replaced by COUNT_BIG in the SQL query being created by EF. The query created by LINQ to EF provider looks very weird to me. Why it is not simply doing something like below to return the scalar count value?
SELECT
COUNT(1) AS [A1]
FROM [dbo].[employeeLevels] AS [Extent1]
It will be really helpful if someone can help me understand the additional logistics being taken care of by EF internally which is why LINQ to EF provider is creating such a query? It seems EF is trying to deal with some additional use cases as well through some common algorithm which results in some sort of generic query as the one created above.
Testing both queries (suitably changing the table) in a DB of mine reveals that they both generate exactly the same query plan. So, the structure shouldn't concern you overly much. In SQL, you tell the system what you want, and it works out how best to do it, and here the optimizer is able to generate the optimal plan given either sample.
As to why LINQ generates code like this, I'd suspect it's just a generalized pattern in its code generator that lets it generate similar code for any aggregation and subsequent transformations, not just for unfiltered counts.

Can I Insert the Results of a Select Statement Into Another Table Without a Roundtrip?

I have a web application that is written in MVC.Net using C# and LINQ-to-SQL (SQL Server 2008 R2).
I'd like to query the database for some values, and also insert those values into another table for later use. Obviously, I could do a normal select, then take those results and do a normal insert, but that will result in my application sending the values back to the SQL server, which is a waste as the server is where the values came from.
Is there any way I can get the select results in my application and insert them into another table without the information making a roundtrip from the the SQL server to my application and back again?
It would be cool if this was in one query, but that's less important than avoiding the roundtrip.
Assume whatever basic schema you like, I'll be extrapolating your simple example to a much more complex query.
Can I Insert the Results of a Select Statement Into Another Table Without a Roundtrip?
From a "single-query" and/or "avoid the round-trip" perspective: Yes.
From a "doing that purely in Linq to SQL" perspective: Well...mostly ;-).
The three pieces required are:
The INSERT...SELECT construct:
By using this we get half of the goal in that we have selected data and inserted it. And this is the only way to keep the data entirely at the database server and avoid the round-trip. Unfortunately, this construct is not supported by Linq-to-SQL (or Entity Framework): Insert/Select with Linq-To-SQL
The T-SQL OUTPUT clause:
This allows for doing what is essentially the tee command in Unix shell scripting: save and display the incoming rows at the same time. The OUTPUT clause just takes the set of inserted rows and sends it back to the caller, providing the other half of the goal. Unfortunately, this is also not supported by Linq-to-SQL (or Entity Framework). Now, this type of operation can also be achieved across multiple queries when not using OUTPUT, but there is really nothing gained since you then either need to a) create a temp table to dump the initial results into that will be used to insert into the table and then selected back to the caller, or b) have some way of knowing which rows that were just inserted into the table are new so that they can be properly selected back to the caller.
The DataContext.ExecuteQuery<TResult> (String, Object[]) method:
This is needed due to the two required T-SQL pieces not being supported directly in Linq-to-SQL. And even if the clunky approach to avoiding the OUTPUT clause is done (assuming it could be done in pure Linq/Lambda expressions), there is still no way around the INSERT...SELECT construct that would not be a round-trip.
Hence, multiple queries that are all pure Linq/Lambda expressions equates to a round-trip.
The only way to truly avoid the round-trip should be something like:
var _MyStuff = db.ExecuteQuery<Stuffs>(#"
INSERT INTO dbo.Table1 (Col1, Col2, Col2)
OUTPUT INSERTED.*
SELECT Col1, Col2, Col3
FROM dbo.Table2 t2
WHERE t2.Col4 = {0};",
_SomeID);
And just in case it helps anyone (since I already spent the time looking it up :), the equivalent command for Entity Framework is: Database.SqlQuery<TElement> (String, Object[])
try this query according your requirement
insert into IndentProcessDetails (DemandId,DemandMasterId,DemandQty) ( select DemandId,DemandMasterId,DemandQty from DemandDetails)

Select N Random Rows with Fluent NHibernate

How do I retrieve N random entities using Fluent NHibernate?
Desired query:
SELECT TOP 5 * FROM MyTable ORDER BY newid()
I'd like to be able to use the Linq repo's for this, but I'm not sure if the result will be optimal. I am not familiar with HQL.
SQL Server-specific Solution
Where Word is the random entity:
IQuery q = _unitOfWork.CurrentSession
.CreateQuery("from Word order by newid()")
.SetMaxResults(5);
var randomWords = q.List<Word>();
Side note: FluentNHibernate is not for querying, it is for mapping and configuration only. Querying is part of "pure" NHibernate.
You can't do it using LINQ directly. The function newid() is SQL Server-specific, so there's no direct equivalent in NHibernate. What you can do here is to query using native SQL by using ISession's CreateSQLQuery method.
See also here for more "deep into NHibernate" method:
How do I select a Random Row using NHibernate's ICriteria API?
You can use Take/Skip linq extensions:
var resultSet = session.Query<TestTable>().Skip(5).Take(10);
With PostgreSql DB this expands to the following SQL statement:
select TestTable.Id, TestTable.Field from TestTable
LIMIT :p0 OFFSET :p1;

Categories