How to get associated tables with LINQ - c#

let's say I have to tables: "Customer" (parent) & "Address" (child). They are associated, so there is a 1:1 relationship between them.
Table<Customer> table = db.GetTable<Customer>();
var query = from c in table
select p;
Is there a possibility to query against tables that are associated with "Customer" using the selected Customer-tables or do I have to get all Address-tables in a separate query?
Besides if I use a DELETE-command on a Customer-table, does this DELETE all the associated tables too?
Thanks in advance,
Prot

If they are related with a foreign key, then it should be very straight forward. The Address should just be a property of Customer.
var query = from c in table
select c.Address;
Or you could do it with a join if a foreign key doesn't exist.
var query = from c in table
join address in [AddressTable] on c.AddressId equals address.Id
select address;
The type of DELETE you're referring to is called a cascade delete. You'll need to enable it on your foreign key (you'll need an FK for this to work). See this thread.

you don't have to get the address out separately, you should be able to just lazy load the address if you have set up an association in the dbml (i.e the arrow linking the tables).
Instellisense should show the property;
var query = from c in table
select p.Address;
for the delete set up an on delete cascade on your foreign key on the tables themselves and this will delete the associated address every time you delete a customer record.

Related

How to select data from entity framework without selecting its icollection(foreign table)

I am using C# to select data from my database. Now i have two table, the first one is aspnetuser, the second one is aspnetuserroles, the aspnetuserroles have the foreign key linkage with aspnetuser table, when i perform the following query
db.AspNetUsers.ToList()
the aspnetroles data will appeared in the aspnetusers data. This will cause my datatable unable to display its data because datatable expect one value in one column parameter. If the aspnet roles data inside that json, it will appear as multiple row and datatable dont accept it.. If i remove that foreign key linkage, my datatable will display without any error.
In this case, what i want is, how to select aspnetusers table without pulling out its foreign table. For eg
db.AspNetUsers.Select(x=>x.AspNetUsers).ToList();
Turn off the LazyLoading. So that the children will not be fetched automatically.
try doing something like this (good for keeping the return object light and leave behind any unwanted columns):
(I have just made up some col name, but you get the idea.)
var result = (from a in db.AspNetUsers
select new AspNetUser { Name = a.Name,
othercol1 = a.othercol1,
othercol2 = a.othercol2,
}).ToList();
Footnote: In reality it is generally not good practice to return the actual db Entity to the front end so you might want to have your own Data Transfer Objects (DTO).
You configured that in the mappings using the Fluent API's methods
HasOptional
HasMany
Ignore
etc. But normally, I create schema-bound views in database and then map that in EF. It works really well in cases when we're only interested in a flattened query without all the joints.
Or use Linq to EF projections as JonhB's answer...
var result = (from a in db.AspNetUsers
select new AspNetUser { Name = a.Name,
...
}).ToList();
Just make sure you don't call ToList on db.AspNetUsers because that would materialize the query on AspNetUsers and all it's foreign key references and as result the projection is done in-memory after the query returns

C# Delete row from multiple tables

Situation: I have 3 tables:
movies (pk:movietitle, movielength....etc)
rentals (pk:personid, fk:movietitle,...etc)
rentingpeople (pk+fk:personid, name, phone...etc)
On my form there is a listbox bindingsourced with the movie titles, next to the listbox there are textboxes bindingsourced from db.movies
When someone click on the rentthismovie button I would like to delete the current rental data about that movie from table rentals and rentingpeople.
I wrote the first part and get an error because of foreign keys problem (I mentioned primary key as pk and foreign key as fk in the tables above)
var search = (from g in db.Rentals
where g.Movietitle == (string)listBox1.SelectedValue select g).First();
db.Rentals.DeleteObject(search);
db.SaveChanges();
I get an error:
The DELETE statement conflicted with the REFERENCE constraint \"FK_Rentingpeople_Rentals\". The conflict occurred in database \"C:\USERS\PC\DOCUMENTS\VISUAL STUDIO 2010\PROJECTS\FILMEK\FILMEK\BIN\DEBUG\DATABASE1.MDF\", table \"dbo.Rentingpeople\", column 'personid'.\r\nThe statement has been terminated.
Because of the primary-foreign key connection I must delete the data from rentingpeople table too as I read from this error but I can't really find a working solution.
The problem is in the db design
movies(pk:movietitle,movielength....etc)
rentals(pk:personid,fk:movietitle,...etc)
rentingpeople(pk+fk:personid,name,phone...etc)
If I got this right, movies contains the list of movies, rentingpeople is the list of people who are renting or have rented, and rentals tracks rentals. If so, rentingpeople.personid should be a pk, and rentals.personid should be an fk to the other, like this:
movies(pk:movietitle,movielength....etc)
rentals(fk:personid,fk:movietitle,...etc)
rentingpeople(pk:personid,name,phone...etc)
if you want to improve search on rentals (assuming any one person can exercise multiple rentals at the same time) you can introduce a non-unique index on personid, or a composite unique index to personid and movietitle on table rentals
You need to delete all the PK and not null references to the object you are deleting before you delete object itself.
You can change non nullable columns to nullable ones if logic allows.
var rentalsToBeDeleted = db.Rentals.Where(o =>o.movieid == movieid).ToList();
for (int i = rentalsToBeDeleted.count; i < 0; i--)
{
db.Rentals.DeleteObject(rentalsToBeDeleted.elementAt(i));
}
after all the referenced deleted.
db.SaveChanges();
writing without VS so mistakes are likely but you should get the idea.

Select entries where only a Foreign Key is present for that ID

I have 4 SQL tables as follows.
Registration
Optional table 1 [RegistrationID Foreign Key]
Optional table 2 [RegistrationID Foreign Key]
Optional table 3 [RegistrationID Foreign Key]
Basically, Registration contains data for ALL those optional tables, but each optional table holds different additional data for that registration, via a foreign key.
Using LINQ to SQL, what's the best way to only select the registrations associated with that Option table?
Pseudo-code would be
select all registrations where an entry in table [x] exists
Appreciate your help
Marko
var results = from r in dc.Registration
join o1 in dc.Optional1 on r.RegistrationID equals o1.RegistrationID
select r;
This will only return the records in table Registration if they have associated records in Optional table 1

LINQ to SQL - No Foreign Keys

No foreign keys defined in the database. So I've setup associations.
problem: can't seem to be able to reference the Role table as expected:
I can get as far as u.UserNamesInRole then can't make the jump to role table.
IEnumerable<fmwebapp1.Old_App_Code.TelerikUsersDataContext.User> userList = (from u in dbTelerik.Users
where u.UsersInRoles.Role.Name = "admin"
select u.UsersInRoles);
where u.UsersInRoles.Role.Name = "admin"
That is incorrect syntax. You need ==.
In a many-to-many relationship, when I want results from one side only, filtered by values on the other side, I usually start my query in the middle of the relation:
To get a role's users:
var users = from ur in context.UsersInRole
where ur.Role.Name == "admin"
select ur.User;
To get a user's roles:
var roles = from ur in context.UsersInRole
where ur.User.UserName == "Jon"
select ur.Role
It would be easiest to add an FK relationship in your database and reimport the tables. EF will then do all the work for you.
If that's not possible, try adding an Association from Role to User and then set the Association Set Name to UsersInRole. Delete the UsersInRole entity from the designer.
You could also compare the EDMX file generated from importing a 'proper' FK relationship between two tables with what you have in your EDMX and then hand edit the XML to match.

LINQ: Associations not functioning correctly for use with innerjoins

Can anyone help, I have been using linq2sql with great success using my associations (foreign keys) to provide inner joins etc...
for example this, works great, the color is stored in a table called Color which has association so i pick it up via Color.Description - Excellent. Same for StructureType its actually an association so i pick it up via the structureType association and the field Description which is in the StructureType table
from v in Houses
select new
{
Id = v.Id,
Color = v.Color.Description,
StructureType= v.StructureType.Description,
Price = v.StructureGroup.StructureGroupTariffs. // doesn't provide anything more only Any, All etc
}
The problem being is that Price i am trying to link, so houses has a Association to StructureGroup which has a association to StructureGroupTariffs but i don't get any more options..
StructureGroupTariffs in an Interlinking table that links StuctureGroup to Tariffs,
I actually did a test here with the interlinking table in Linq and it works! like so
from g in StructureGroupTariffs
select new
{
Price = g.Tariff.Price
}
So i am a little confused, why (see above) this
Price = v.StructureGroup.StructureGroupTariffs.
only returns methods like Any, All etc but not the association....
Can anyone help please
StructureGroupTariffs is an EntitySet not an EntityRef, i.e. it contains many objects rather than a single object. You can't extract the 'many' into the 'single' that you are assembling in your query.
EDIT
I suspect that your House table has a StructureGroup and that there is a Tariffs table, in between is a StructureGroupTariffs table that holds FK references to each of the other tables allowing there to be many tariffs for each structure group (irrespective of whether there actually are many tariffs). Hence Linq using an EntitySet to refer to the StructureGroupTariffs.

Categories

Resources