Entity Framework linq to SQL relationship - asp.net-mvc

table person
personid
personname
table customer
customerid
personid
orderinfo
I am entity framework and want to select few columns but on join I am unable to join customer and person table based on personid. all foreign key and primary keys are in place
var dealercontacts = from contact in database.person join dealer in database.customer on contact.personid equals dealer.personid
select personname, orderinfo;
I am receiving error that customer does not contain personid

If all of your foreign keys are setup correctly, you should be able to call it as such:
var dealercontacts = from contact in database.person
select contact.personname, contact.customer.orderinfo
Does this work to solve your problem?
EDIT: You may have to switch the query around and write it as such:
var dealercontacts = from customer in database.customers
select customer.person.personname, customer.orderinfo

Related

Optimizing SQL query using JOIN instead of NOT IN

I have a sql query that I'd like to optimize. I'm not the designer of the database, so I have no way of altering structure, indexes or stored procedures.
I have a table that consists of invoices (called faktura) and each invoice has a unique invoice id. If we have to cancel the invoice a secondary invoice is created in the same table but with a field ("modpartfakturaid") referring to the original invoice id.
Example of faktura table:
invoice 1: Id=152549, modpartfakturaid=null
invoice 2: Id=152592, modpartfakturaid=152549
We also have a table called "BHLFORLINIE" which consists of services rendered to the customer. Some of the services have already been invoiced and match a record in the invoice (FAKTURA) table.
What I'd like to do is get a list of all services that either does not have an invoice yet or does not have an invoice that's been cancelled.
What I'm doing now is this:
`SELECT
dbo.BHLFORLINIE.LeveringsDato AS treatmentDate,
dbo.PatientView.Navn AS patientName,
dbo.PatientView.CPRNR AS patientCPR
FROM
dbo.BHLFORLINIE
INNER JOIN dbo.BHLFORLOEB
ON dbo.BHLFORLOEB.BhlForloebID = dbo.BHLFORLINIE.BhlForloebID
INNER JOIN dbo.PatientView
ON dbo.PatientView.PersonID = dbo.BHLFORLOEB.PersonID
INNER JOIN dbo.HENVISNING
ON dbo.HENVISNING.BhlForloebID = dbo.BHLFORLOEB.BhlForloebID
LEFT JOIN dbo.FAKTURA
ON dbo.BHLFORLINIE.FakturaId = FAKTURA.FakturaId
WHERE
(dbo.BHLFORLINIE.LeveringsDato >= '2017-01-01' OR dbo.BHLFORLINIE.FakturaId IS NULL) AND
dbo.BHLFORLINIE.ProduktNr IN (110,111,112,113,8050,4001,4002,4003,4004,4005,4006,4007,4008,4009,6001,6002,6003,6004,6005,6006,6007,6008,7001,7002,7003,7004,7005,7006,7007,7008) AND
((dbo.FAKTURA.FakturaType = 0 AND
dbo.FAKTURA.FakturaID NOT IN (
SELECT FAKTURA.ModpartFakturaID FROM FAKTURA WHERE FAKTURA.ModpartFakturaID IS NOT NULL
)) OR
dbo.FAKTURA.FakturaType IS NULL)
GROUP BY
dbo.PatientView.CPRNR,
dbo.PatientView.Navn,
dbo.BHLFORLINIE.LeveringsDato`
Is there a smarter way of doing this? Right now the added the query performs three times slower because of the "not in" subquery.
Any help is much appreciated!
Peter
You can use an outer join and check for null values to find non matches
SELECT customer.name, invoice.id
FROM invoices i
INNER JOIN customer ON i.customerId = customer.customerId
LEFT OUTER JOIN invoices i2 ON i.invoiceId = i2.cancelInvoiceId
WHERE i2.invoiceId IS NULL

Join multiple FK values in one table

I'm writing some access queries and I'd like some help on a particular query. I'm still very new to SQL. Here is a simplified version of my tables:
Project Details
---------------
projectID (PK)
projectStartDate
projectEndDate
projectName
managerID (FK)
leadID (FK)
coleadID (FK)
Employee
--------
empID (PK)
empName
The managerID, leadID, and coleadID all correspond to an empID. I'd like to retrieve the Project Details table, but replace the IDs with the names of the employees. I've successfully been able to do this for one FK at a time using an inner join, but can't figure out a way to accomplish this for all roles.
It would also be nice to be able to change the attribute names on the results to managerName, leadName, and coleadName.
Thanks!
It's the same way, you probably have done it for one ID:
SELECT pd.*
, emp_m.empName ManagerName
, emp_l.empName LeadName
, emp_c.empName ColeadName
FROM ProjectDetails pd
, Employee emp_m
, Employee emp_l
, Employee emp_c
WHERE pd.managerID = emp_m.empID(+)
AND pd.leadID = emp_l.empID(+)
AND pd.coleadID = emp_c.empID(+)
The (+) is for an outer join, so it will select all records of the ProjectDetails table, no matter if it can match the manager, lead or colead.

How to implement multi layered "Include" in Entity framework 3.5 (VS 2008)

My DB have two tables - Question and Topic. To implement many-to-many relation, there is a mapping table which has following structure:
Table TopicQuestionMapping
int ID (Primary Key)
int QuestionID (Foreign key to Question table)
int TopicID (Foreign key to Topic table)
Now, in my EF I got something like
ViewData.Model = DB.QuestionMaster.Include("TopicQuestionMapping").First(x => x.ID == id);
and then I try to fetch topic like
Model.TopicQuestionMapping.First().TopicMaster.Name
(for simplification, I am just considering the first record)
The query populates the TopicQuestionMapping (I am getting count = 1). But the TopicMaster is null. Howe can I get it work?
It is something like Table A refer to Table B. Table B refer to Table C. I need to get data from Table C.
Include uses .'s to navigate the object graph.
So like .Include("TableA.TableB.TableC")
http://msdn.microsoft.com/en-us/library/bb896272.aspx

NHibernate: getting object model with HQL using a join on table

I am having difficult time trying to figure out how to get a mapped object using a join on a table (not mapped table).
Tables:
DataForm: (Id, AliasName (FK), ...)
Customer: (Id, ...)
CustomerAliases: (PK AliasName, CustomerId (FK))
So aliases are unique for every Customer and Customer may have many aliases.
Code:
DataForm.Customer - this is what I need
So how do I write the HQL in the getter?
Since CustomerAliases table is just a list of aliases I don't have it mapped to a class but is accessed through on the Customer. How can I get Customer using AliasName?
If it was normal SQL I would just do:
SELECT * From Customer c
INNER JOIN CustomerAliases ca ON ca.AliasName = 'AliasNameProvided'
WHERE ca.CustomerId = c.Id
HQL can only be use on mapped classes. When you leave the mapped area, you need to use SQL which looks exactly like the SQL in your question.
I would map it:
class Customer
{
IList<string> AliasNames { get; private set; }
}
mapping:
<class name="Customer">
<!-- ..... -->
<bag name="AliaseNames" table="CustomerAliases">
<key column="CustomerId"/>
<element column="AliasName"/>
</bag>
</class>
query:
from Customer c join c.AliasNames n
where n = :alias

LINQ to SQL and Data Projection, MVC

HI I have a table with some some values (IDs), and of course when i get the result i got just the int IDs, but i want to put it more user friendly, for example when its the number 1, i want to put the string "Avaible", when its 2 "Not avaible", im on an N tiers enviroment and i need to get this done on the Model, whats the best way to accomplish this, i have to declare another class to project the strings, or must i use something like a dictionary, Key -> Value.
right now i just have this
return from t in db.products where t.productID==productID select t;
If you are using Linq to SQL you need another table to contain product status:
Table Name: Product Status
Fields: ProductStatusID int Indentity Primary Key
ProductStatus nvarchar(50)
Add a field to your Products Table:
Field to Add: ProductStatusID int
Add some statuses to your new table, and set the ProductStatusID of each product to an appropriate status id.
Add a constraint that connects the two ProductStatusID fields together. The easiest way do this is to create a diagram in SQL Server Management Studio Express, drag both tables onto the diagram, and then drag the ProductStatusID field from the ProductStatus table to the Products table, and click OK on the dialog that opens.
Rebuild your Linq to SQL data classes. You do this by deleting and recreating the DBML file, and dragging your tables into the designer again.
When you get a products object (p) from your dataContext object, you should now see this:
p.ProductStatus <-- The text description of the product's status.
Linq to SQL will reach into your ProductStatus table, and lookup the appropriate status description.

Resources