I'm trying to write an SQL query where all of a certain group meets a condition.
Update
The Simplifed Table Structure would look like this
ID, TitleID, BlockFromSale
---------------------------
1 | 1 | true
2 | 1 | true
3 | 1 | true
4 | 2 | false
5 | 2 | true
this table would only return the the items TitleID 1.
In actuality I only need the title ID and not the whole item but either will satisfy the conditions.
How Could I write This Linq Query in SQL?
var Query = Data.Items.GroupBy(t => t.TitleID).Where(i => i.All(b => b.BlockFromSale == true));
I try to look at the Sql Query but it just instantly casts it to an object.
Basically I just Need a query that Grabs out all TitleIDs who for each item BlockFromSale is set to true so for the example from the table above it would only return TitleID, 1
It is possible to see the generated SQL of a LINQ query by using the Log property of the query. How to: Display Generated SQL shows an example of this. Basically, the web site shows this example:
db.Log = Console.Out;
IQueryable<Customer> custQuery =
from cust in db.Customers
where cust.City == "London"
select cust;
foreach(Customer custObj in custQuery)
{
Console.WriteLine(custObj.CustomerID);
}
If you want to check predicate p for all rows of a set you can write
NOT EXISTS (... WHERE NOT(p))
Because All(p) == !Any(!p) in pseudo-syntax.
I would guess that ORMs do it this way, too.
There isn't an easy way to do what your asking but a simple but some what slow way would be to use a subQuery
SELECT DISTINCT i.TitleID
FROM Items i
WHERE i.TitleID not in
(SELECT DISTINCT TitleID
FROM items it
WHERE it.BlockFromSale = 0)
so it will remove the titleids who have a false.
Related
this is my code to fetch data from multiple table and return it as json. However it only allow one to one relationship.
Problem: DoctorNote have multiple result sets, i am having problem fetching the data. Error"Sequence contains more than one element". Any suggestion on how i can fetch the many relationship results?
var person = (from p in _context.Patients
join e in _context.PatientAllocations
on p.patientID equals e.patientID
join d in _context.DoctorNotes
on p.patientID equals d.patientID
where p.patientID == patientID
select new
{
patient_patientID = p.patientID,
patient_isDeleted = p.isDeleted,
patient_isApproved = p.isApproved,
patient_updateBit = p.updateBit,
patientallocation_caregiverID = e.caregiverID,
patientallocation_doctorID = e.doctorID,
DoctorNote_doctorNoteID = d.doctorNoteID,
DoctorNote_note = d.note,
DoctorNote_createDateTime = d.createDateTime,
DoctorNote_patientID = d.patientID,
DoctorNote_isApproved = d.isApproved,
DoctorNote_isDeleted = d.isDeleted,
}).ToList().SingleOrDefault();
return Ok(person);
Exception is thrown by SingleOrDefault method, so based on that fact it seems your query returns more than one element.
To get collection of DoctorNotes, just remove SingleOrDefault method from your query
You are using SingleOrDefault() which assume that your query will return at most one record. You may try FirstOrDefault() it assume query can return any number of record and you want first.
You may see this to understand difference between the two
| 0 values | 1 value | > 1 value
FirstOrDefault | Default | First value | First value
SingleOrDefault | Default | First value | Exception
The query still returns 3 DocterNotes.
The FirstOrDefault is on the total query, not on the DocterNotes.
Can you add a where clause?
For example, this should work:
where p.patientID == patientID
and DoctorNote_doctorNoteID == 3
Ok, so i have two questions. The first is, let's say that i have an EF called "EntitiesDefinitions", which holds a data table named "stringData" where each cell is defined as a varchar(100) like so:
----------------------------------------------
| | column1 | column2 | column3 | ... |
----------------------------------------------
| row1 | "1,2,3,4" | "5,6,7,8" | "9,a,b,c" | ... |
----------------------------------------------
| row2 | "d,e,f,g" | "h,i,j,k" | "l,m,n,o" | ... |
Each cell contains 4 pieces of information separated by a comma. So what i would like to know is, if there's a way for me to perform a Linq search for the (as an example) the 2rd piece of information of every cell in column1?
using (EntitiesDefinitions ef = new EntitiesDefinitions())
{
var v = (from a in ef.stringData where (a.column1... == "e") select a);
}
I know I could just make 4 columns per cell (column1_1, column1_2, ...column2_1, column2_2,...), but that wouldn't work if i get a table with +250 original columns. So is there a way to perform such searches?
The other question is also related to this. Back in ASP.NET i could send queries to my sql using a string like this:
var stringSql = "SELECT * FROM" + "stringData" + "WHERE ([" + "column1" + "] =" + "e" + ")" + "ORDER by ["+ "column1" +"] ASC;"
Basically, i could define which tables to search for given a string value that represented that property/column. Is there a way to do that with EF linqs?
using (EntitiesDefinitions ef = new EntitiesDefinitions())
{
var v = (from a in ef.stringData where (a.["column1"]... == "e") select a);
}
I'm fairly new with MVC and EF, so I would like to know if this is possible.
From what I understand from your question you can try this out if u sure its always not null:
var res = ef.stringData.Where(c => c.column1.Split(',')[1] == "e")
And for the Second Question where you type "ef.stringData" the name of the table you are querying is "stringData" there is no other way to specify the table name or only if you want to write raw sql queries in EF.
After Fehintola suggestion i was able to do more research specific to those subjects and I was able to find a solution for both questions. In case anyone is interested here's what i came up with:
For the first question, while is not elegant, we can encapsulate data inside in specific characters/delimiters and then we can process search results in nested searches. For example:
using (EntitiesDefinitions ef = new EntitiesDefinitions())
{
//Data could look like";1;*2*&3#"
var v = (from a in ef.stringData where select a); //to store the table
v = c.Where(f => f.column1.Contains("*2*")) //look for the second value
v = x.Where(f => f.column1.Contains("#4.3#"));//look for the forth value
//Do some other stuff...like sending the data to a table
}
For the Second question, you can make raw sql queries like this:
string sqlExample = #"SELECT VALUE a FROM ef.stringData AS a WHERE (a.column1 == '*2*')";
var test = ef.CreateQuery<stringData>(sql).AsQueryable();
This was you can just have variables placed in the sqlExample string to build your query dynamically and you'll get back a IQueryable object you can use to, for example, pass into a table.
I hope this helps someone in the future and thanks to everyone that provided suggestion.
I have a dataGridView with multiple server roles. I'd like to get a collection of server names with roles "not like" webSrvr or client. For example.. DGV:
Servers | Server 1 | Server 2 | Server 3 | Server 4 | Server 5
Role | Database | Proxy | WebSrvr | Client | DC
Is there an easy linq statement to pull the Server 1, 2 and 5 column headers (names)? The reason I'd want to use "not like" or the equivalent is because the roles can have additional values at the end of it. Thoughts?
You could do pretty much what you want ...
var your_name = from str in your_list_source_here
where (str == some_condition)
select ( new { create your object here } )
you could just have the columns you want in the create your object here
here's an example from Linqpad , to illustrate how you can use the new object ...
var words =
from word in "The quick brown fox jumps over the lazy dog".Split()
orderby word.ToUpper()
select word;
var duplicates =
from word in words
group word.ToUpper() by word.ToUpper() into g
where g.Count() > 1
select new { g.Key, Count = g.Count() };
His objects will have the letter and the amount of time it repeats...
Have the following table structure
I need the count of transcriptions by statuses where the records do not have a workflow folder. This does the trick:
from p in Transcriptions
where p.WorkflowfolderID == null
group p by p.TranscriptionStatus.Description into grouped
select new
{
xp=grouped.Key,
xp1= grouped.Count(),
}
Now I need to add the number of records where the Dueon date is in the past as in it is past the due by date.Something like
EntityFunctions.DiffHours(p.DueOn,DateTime.Today)>0
How do I include this in the resultset without firing 2 SQL queries? I am happy to get it as a third column with the same value in every row. Also is there anyway to get the percentage into the mix as in:
Status | Count | % |
------------------------------
Status1 | 20 | 20%
Status2 | 30 | 30%
Status3 | 30 | 30%
Overdue |20 | 20%
I have added Overdue as a row but perfectly happy to get it as a column with the same values.
Edited Content
Well this is the best I could come up with. Its not a single query but there is only one SQL trip. The result is:
Status | Count
----------------
Status1 | 20
Status2 | 30
Status3 | 30
Overdue |20
var q1= from p in Transcriptions
where p.WorkflowfolderID == null
group p by p.TranscriptionStatus.Description into grouped
select new
{
status= (string)grouped.Key,
count= grouped.Count()
};
var q2 =(
from p in Transcriptions select new {status = "Overdue",
count = (from x in Transcriptions
where x.DueOn.Value < DateTime.Now.AddHours(-24)
group x by x.TranscriptionID into
grouped select 1).Count() }).Distinct();
q1.Union(q2)
It is a Union clause with the % calculation to be done once the results are returned. The weird thing is that I couldn't figure out any clean way to represent the following SQL in a LINQ statement which has resulted in the rather messy LINQ in the var q2.
SELECT COUNT(*) , 'test' FROM [Transcription]
You can add a condition to Count:
from p in Transcriptions
where p.WorkflowfolderID == null
group p by p.TranscriptionStatus.Description into grouped
select new
{
xp=grouped.Key,
xp1= grouped.Count(),
xp2= grouped
.Count(p => EntityFunctions.DiffHours(p.DueOn, DateTime.Today) > 0)
}
By the way, with entity framework you can also use p.DueOn < DateTime.Today.
#Gert Arnold
from p in Transcriptions
where p.WorkflowfolderID == null
group p by p.TranscriptionStatus.Description into grouped
select new
{
status= (string)grouped.Key,
count= grouped.Count(),
overdue= grouped.Count(p => p.DueOn < EntityFunctions.AddHours(DateTime.Today, -24)),
}
The above query does work as I wanted it to . It produces the outcome in the format
Status| Count | Overdue
----------------------
status1|2|0
status2|1|1
The only downside is the generated SQL is running 2 queries BOTH with inner joins . My original idea with the Union may be a better idea performance wise but you answered my query and for that I am grateful.
Can this query be represented in some other cleaner manner than my above attempt -
SELECT COUNT(*) , 'test' FROM [Transcription]
I have a Gridview with a column called Quantity. Each product has it own quantity. I need to show as many rows as the quantity says.
For example, if I have
Car | 4 | $ 20
I need to show 4 rows like
Car | 1 | 20
I can't find a way of doing this. I am using linq to retrieve the data from the database and that is the DataSource of my Gridview.
You can do it using the linq Range method. Assuming you have a linq source like this (trivial example)
var result =
from r in db.SourceTable
select new { r.Name, r.Quantity, r.Price };
Add this to the query
var result =
from r in db.SourceTable
from s in Enumerable.Range(1, record.Quantity)
select new { r.Name, 1, r.Price };
However, this is probably not supported by entity framework (and probably not in any other ORM) so you may need to call .ToList() or .AsEnumerable() first.