Trouble converting a bit of TSQL to LINQ to Entities - c#

Sorry about the vague title, not sure what verbage I should be using. I have a query similar to this (re-worked to save space):
SELECT
*
FROM
Publishers p
INNER JOIN Authors a
ON p.AuthorID = a.AuthorID
INNER JOIN Books b
ON a.BookID = b.BookID
WHERE
p.PublisherName = 'Foo'
ORDER BY
b.PublicationDate DESC
I tried to re-write it as such:
var query =
from publisher in ctx.Publishers
from author in publisher.Authors
from books in author.Books
...
but got the following error:
Error 1 An expression of type 'Models.Books' is not allowed in a
subsequent from clause in a query expression with source type
'System.Linq.IQueryable<AnonymousType#1>'. Type inference failed in the
call to 'SelectMany'.
I can re-write the LINQ to make it work by just joining the tables, as I would in SQL, but I thought I could accomplish what I want to do by their relationships - I'm just a bit confused why I can get publisher.Authors, but not author.Books.

Check that you have a relationship in your DB from Authors to Books.

Try this...
var result = (from pItem in ctx.Publishers
join aItem in ctx.Authors on pItem.AuthorId equals aItem.AuthorId
join bItem in ctx.Books on pItem.BookId equals bItem.BookId
where pItem.PublisherName== "Foo"
select new {
// Fields you want to select
}
).ToList();
i don't know exact relationship of the tables but you can an idea from this one.

Related

Conversion of Sql query to linq

I am trying to convert sql query for select to linq query using EF in MVC but really got stuck with an error.
In SQL I'm able to get 6 records for my query,similarly when I try to convert this to linq it shows some error.
Following is my query in SQL:
SELECT
PurchaseOrderMaster.*, PurchaseOrderDetails.*, Vendor.*,
BusinessUnit.*, InvoiceMaster.*, TenantEmployee.*
FROM
PurchaseOrderMaster
INNER JOIN
PurchaseOrderDetails ON PurchaseOrderMaster.TenantID = PurchaseOrderDetails.TenantID
AND PurchaseOrderMaster.PurchaseOrderNumber = PurchaseOrderDetails.PurchaseOrderNumber
AND PurchaseOrderMaster.PurchaseOrderDate = PurchaseOrderDetails.PurchaseOrderDate
INNER JOIN
InvoiceMaster ON PurchaseOrderMaster.TenantID = InvoiceMaster.TenantID
AND PurchaseOrderMaster.PurchaseOrderNumber = InvoiceMaster.PurchaseOrderNumber
AND PurchaseOrderMaster.PurchaseOrderDate = InvoiceMaster.PurchaseOrderDate
INNER JOIN
BusinessUnit ON PurchaseOrderMaster.TenantID = BusinessUnit.TenantID
AND PurchaseOrderMaster.BusinessUnitID = BusinessUnit.BusinessUnitID
INNER JOIN
TenantEmployee ON PurchaseOrderMaster.TenantID = TenantEmployee.TenantID
INNER JOIN
Vendor ON PurchaseOrderMaster.TenantID = Vendor.TenantID
AND PurchaseOrderMaster.VendorID = Vendor.VendorID
For this query I am able to get 6 records .
And my linq query is:
return (from pom in db.PurchaseOrderMaster
join pod in db.PurchaseOrderDetails on pom.TenantID equals pod.TenantID
where pom.PurchaseOrderNumber == pod.PurchaseOrderNumber && pom.PurchaseOrderDate == pod.PurchaseOrderDate
join inv in db.InvoiceMaster on pom.TenantID equals inv.TenantID
where pom.PurchaseOrderNumber == inv.PurchaseOrderNumber && pom.PurchaseOrderDate == inv.PurchaseOrderDate
join bu in db.BusinessUnit on pom.BusinessUnitID equals bu.BusinessUnitID
join te in db.TenantEmployee on pom.TenantID equals te.TenantID
join v in db.Vendor on pom.TenantID equals v.TenantID
where pom.VendorID == v.VendorID
orderby pom.PurchaseOrderNumber ascending, pom.PurchaseOrderDate descending
select new { pom, pod, inv, bu, te, v }).ToList();
At the time of debugging,following is the error that I'm getting:
{"Invalid column name 'invoiceMasterModel_TenantID'.\r\nInvalid column name 'invoiceMasterModel_PurchaseOrderNumber'.\r\nInvalid column name 'invoiceMasterModel_PurchaseOrderDate'.\r\nInvalid column name 'invoiceMasterModel_InvoiceNumber'.\r\nInvalid column name 'invoiceMasterModel_InvoiceDate'.\r\nInvalid column name 'tenantEmployeeModel_TenantID'.\r\nInvalid column name 'tenantEmployeeModel_EmployeeID'."}
Inside Invoice Table it is not able to find some of the columns and hence throwing the error according to me..
I tried with many possible ways but was unable to solve this.
Any ideas..?
Problem was with my Entity.
What I did is,I added my entity again and according to that I recreated models for the associated tables removing the earlier ones.
It solved my problem finally .
I found this link Entity Framework 5 Invalid Column Name error related to somewhat similar problem.
Here also similar kind of error happened after the date time field. Check if your datetime field PurchaseOrderDate is nullable.
Many tools exist that can convert your sql queries to linq, in case you don't wanna write it urself. Try the following sites, works well in my case:
http://www.sqltolinq.com/
http://www.linqpad.net/

LINQ Group by and having where clause

Below is the SQL Query I am trying to translate
SELECT dbo.Contracts.Supplier
FROM dbo.Contracts INNER JOIN dbo.Products ON dbo.Contracts.Product = dbo.Products.Product
where dbo.Products.ProductGroup='Crude'
GROUP BY dbo.Contracts.Supplier
Am I doing something wrong because I do not get same results with the following LINQ
var result = from c in context.Contracts
join p in context.Products on c.Product equals p.Product1
where p.Product1.Equals("Crude")
group c by c.Supplier into g
select new { supplier = g.Key };
It is generating a weird statement
SELECT
1 AS [C1],
[Distinct1].[Supplier] AS [Supplier]
FROM ( SELECT DISTINCT
[Extent1].[Supplier] AS [Supplier]
FROM [dbo].[Contracts] AS [Extent1]
WHERE N'Crude' = [Extent1].[Product]
) AS [Distinct1]
Using distinct would work but to get same results, LINQ should be generating a statement like so (it's like it is ignoring the join):
SELECT distinct dbo.Contracts.Supplier
FROM dbo.Contracts INNER JOIN dbo.Products ON dbo.Contracts.Product = dbo.Products.Product
where dbo.Products.ProductGroup='Crude'
I'm assuming that you are using 'EntityFramework' or 'Linq To SQL'. If so, you should be able to use navigation properties to navigate to product and filter invalit results out. This way your query might look something like this:
var result = (from c in context.Contracts
where c.Products.Any(p => p.ProductGroup == "Crude")
select c.Supplier).Distinct();
It will automatically convert into correct query (in this case possibly without join even, just using Exists sql keyword) and return distinct suppliers. This is if I understand your objective correctly - you want to obtain all suppliers assigned to contracts that contain product from 'Crude' product group.
Basically you should try to avoid using joins from linq to sql or linq to entities as much as possible when you can use navigation properties. System will probably be better at converting them into specific sql.

entity to SQl,linq to sql query

Find all the different persons that appear in the table charged with the responsible entity that creates a connection more or more persons and entities projects?
how to convert sql query in there technologies?
Sql query is
select distinct p.PersonID,p.FirstName,p.LastName
from Responsible tr inner join People p on p.PersonID=tr.People_PersonID;
My attemot is
string query = #"SELECT value empl
FROM TicketBaseEntities.Responsible AS tr
INNER JOIN TicketBaseEntities.People AS empl
on empl.PersonID =tr.Responsibles.People_PersonID where tr.Responsibles !=null";
return Context.CreateQuery<Employee>(query).Distinct();
Error message is:
'People_PersonID' is not a member of 'Transient.collection[TicketBaseModel.Person(Nullable=True,DefaultValue=)]'. To extract a property of a collection element, use a subquery to iterate over the collection. Near simple identifier, line 5, column 63.
(from tr in Responsible
join from p in People on tr.People_PersonID equals p.PersonID
select p.PersonID,p.FirstName,p.LastName).Distinct()
You can Implement IComparer interface to use Distinct() function for Class People

Ruby Sequel Equivalent to LINQ to SQL select anonymous objects

I've got some C# code with a LINQ query I'm trying to translate to Ruby and am using Sequel as my DB ORM. The linq query just performs some joins and then returns an anonymous object containing references to the joined entities. I've got the code translated and operating correctly but it just returns all of the columns from each table and I'd like to wrap each set of columns up in its own object similarly to how it is done in the C# code.
LINQ Query
from s in slots
join tu in _dbContext.table_usages on s.id equals tu.slot_id
join r in _dbContext.Reservations on tu.reservation_id equals r.ReservationID
join o in _dbContext.orders on r.OrderID equals o.OrderID
join c in _dbContext.Contacts on r.ContactID equals c.ContactID
where tu.reservation_id != null &&
r.state != ReservationStates.Cancelled
select new { SlotId = s.id, Reservation = r, Order = o, Contact = c, TableUsage = tu };
Ruby Code:
select(:slots__id, :reservations.*, :orders.*, :restaurant_customers.*, :table_usages.*)
.filter(slots__restaurant_id: restaurant_id, slots__removed: false)
.filter(slots__slot_time: start_time..end_time)
.join(:table_usages, slot_id: :id)
.join(:reservations, id: :table_usages__reservation_id)
.join(:orders, id: :reservations__order_id)
.join(:restaurant_customers, id: :reservations__contact_id)
.filter('table_usages.reservation_id is not null')
.filter('reservations.state != ?', ReservationStates.cancelled)
I'm unable to find a way of accomplishing this via the docs but I thought I would see if anyone has done something similar in a way that I haven't thought of yet.
Thanks!
I'm assuming you are just referring to the last two lines:
.filter('table_usages.reservation_id is not null')
.filter('reservations.state != ?', ReservationStates.cancelled)
Which you could handle via:
.exclude(:table_usages__reservation_id=>nil)
.exclude(:reservations__states=>ReservationStates.cancelled)
exclude operates as an inverse filter.

How to write SQL SELECT INNER JOIN with multiple conditions (with LIKE) query to LINQ to SQL

I've been looking up how to do this, and I found something close, but not quite what I'm looking for. I wonder if this might help others as well, but I could really use the help. I've got a pretty simple SELECT statement I need to convert into LINQ to SQL to speed up searches in our software:
SELECT Animals.*
FROM Animals
INNER JOIN AnimalAliases
ON Animals.AnimalID = AnimalAliases.AnimalID
AND AnimalAliases.Alias LIKE N'%USERINPUT%';
Basically, I want to be able to do a Inner join with multiple conditions, but one of the conditions has nothing to do with one of the tables, the LIKE statement, which is where I get stuck.
var query =
from animal in context.Animals
join animalAlias in context.AnimalAliases
on new { animal.AnimalID, "USERINPUT" }
equals new { animalAlias.AnimalID, animalAlias.Alias }
select animal;
but that doesn't work obviously, because I dont want EQUALS to USERINPUT, I want to perform various LIKE operations on it..
Anyone have any insight?
I think what you're looking for is just a normal WHERE clause?
var query = from animal in context.Animals
join animalAlias in context.AnimalAliases on animal.AnimalID equals animalAlias.AnimalID
where animalAlias.Alias.Contains(USERINPUT)
select animal;
The alias text is not part of the foreign key relationship - so it shouldn't be in the join.
Update - after comments - including from #Steven - while the query above is correct and does mimic the original SQL - it might be wise to use Distinct() on the output - this will prevent the case where multiple alias matches could occur for a single animal.
var query = (from animal in context.Animals
join animalAlias in context.AnimalAliases on animal.AnimalID equals animalAlias.AnimalID
where animalAlias.Alias.Contains(USERINPUT)
select animal).Distinct();
This will do the trick:
IQueryable<Animal> query =
from animal in context.Animals
where animal.AnimalAliases
.Any(a => a.Alias.Contains("USERINPUT"))
select animal;
Alternatively, you can do it the other way around (start at the AnimalAlias entity instead of starting at the Animal entity):
IQueryable<Animal> query = (
from animalAlias in context.AnimalAliases
where animalAlias.Alias.Contains("USERINPUT")
select animalAlias.Animal)
.Distinct();

Categories