Say I have 3 tables, Cars, Persons, CarOwners.
Cars is just a table of cars and Persons are different people that can own cars. CarOwners has a CarId and a PersonId relationship and a CarOwnerId PK.
If I just create the relationship and then drag them to the linq context, a property of the Person class will be generated called CarOwners. To get the cars that this person owns I would have to do the following query:
var cars = person.CarOwners.Select(c=> c.Car);
But I would like to be able to do:
var cars = person.Cars;
Is that at all possible? The extra step is quite annoying.
You can just create a new property on Person:
public partial class Person
{
public IEnumerable<Car> Cars
{
get { return this.CarOwners.Select(c => c.Car); }
}
}
Or upgrade to Entity Framework where you can separate logical model from physical model.
Try to remove the CarOwnerId from CarOwners in your sql database. Then select CarId and PersonId in designer mode in SSMS (using shift key), right click and select `Set Primary Key.
In EF 4, you'll get only navigation keys in your model this way (you can use: Person.Cars and Car.Persons). Not sure about L2S.
Related
I have a database table that stores user entered localization strings for many other tables in the database.
PK
TableName
RecordID
Field
Value
1
TableA
1
Name
2
TableA
1
Category
3
TableB
1
Make
4
TableB
1
Model
I don't know if there is a term for this type of table so sorry for the vague title. When querying for this data in SQL we would simply join on TableName and RecordID.
How would I go about mapping this in Entity Framework? Is a navigation property possible with a table like this?
I was hoping that something could be done in OnModelCreating to configure navigation properties on the base entity to only include records where TableName == "Table_". If possible I'd like to avoid having to add a Where clause in an .Include statement every time a record is queried.
public class TableA
{
// This should only include PK 1-2
public List<LocalizedString> LocalizedStrings { get; set; }
}
public class TableB
{
// This should only include PK 3-4
public List<LocalizedString> LocalizedStrings { get; set; }
}
The only possible solution I can think of is to try using TPH inheritance. With the TableName as the discriminator I believe I would need to create a class for every type. TableALocalizedString, TableBLocalizedString, etc. If possible I'd like to avoid that, this table references a lot of other tables.
How can I add a custom property to my LINQ-to-SQL model that automatically joins a value from a foreign table, effectively de-normalizing an association?
My (simplified) database model:
Customer Group
------------ ----------
CustID [PK] GroupID [PK]
FirstName GroupName
LastName ...
GroupID [FK]
...
My first (simplified) approach:
public partial class Customer
{
public string GroupName
{
get { return this.Group.GroupName; }
}
}
In reality, GroupName is a few associated tables away, requiring me to join, filter, group, select, etc. to get to it. All doable with plain SQL.
Accessing GroupName triggers a separate SQL query. I know I could preload the Group model with loadOptions.LoadWith<Customer>(c => c.Group), but I would need to remember that and do it for every new DataContext, and I don't really need the Group model (and all models inbetween) at all. I just want to have the GroupName as readonly string on the Customer.
So I basically want to extend the model like I would do with a SQL query:
SELECT Customer.*, Group.GroupName
FROM Customer
INNER JOIN Group
ON Customer.GroupID = Group.GroupID
Can this be done with a LINQ-to-SQL model? Alternatives?
We have database which does not have proper foreign keys set. We are now generating edmx using this database. What we want is to set navigation property so that we can get corresponding details from other table. Here is example what exactly we are looking for.
Lets say There is a table Employee and Department. Now in database there is no relation between these tables but Employee has DepartmentId which is taken from Department table.
When we fetch Employee we get only DepartmentID but we also want to get Department as property along with it so that we can get information like "DepartMentName", "Location" which is stored in Department table.
We tried adding Navigation property in EDMX file but it fails and keeps giving error related to relation.
Please help
You can go with something like this. Create a wrapper class for Employee and Department.
public class EmpDept
{
public Employee Employee {get; set;}
public Department Department {get; set;}
}
public IEnumberable<EmpDept> GetEmployeesWithDeptpartment()
{
var result = from e in context.Employee
where e.Id == somevalue
select new EmpDept()
{
Employee = e,
Department = context.Department.Where(d => d.Id == e.DepartmentId)
};
return result.ToList();
}
It means you have an extra class, but it's quick and easy to code, easily extensible, reusable and type-safe.
Hope this helps
I'm having a problem with Dapper when I do not expose my foreign keys and child collections in the POCO model.
Let's take a simple example with the two entities:
Bike (Id, ModelName)
Tire (Id, Tread)
In the database each Tire has a foreign key to Bike. But my model does not.
From the database, I want to materialize this structure into a Dictionary<Bike, IEnumerable<Tire>>. Where each Bike (unique) will have two tires.
I could select this one-to-many relationship using the following query:
SELECT b.Id, b.ModelName, t.Id, t.Tread
FROM Bike b
JOIN Tire t ON b.Id = t.bike_id
In order to map that using Dapper, I have done the following:
var dbResult = connection.Query<Bike, Tire, KeyValuePair<Bike, Tire>>("sql-query-above",
(a, s) => new KeyValuePair<Bike, Tire>(a, s);
splitOn: "Id");
And to turn that result into my dictionary, using LINQ:
Dictionary<Bike, IEnumerable<Tire>> dict = dbResult.GroupBy(g => g.Key, g => g.Value).ToDictionary(g => g.Key, g => g.AsEnumerable());
And it correctly returns the data structure:
Bike #1
- Tire #1
- Tire #2
Bike #2
- Tire #3
- Tire #4
But is this the most efficient way of materializing this data structure?
An alternative would be to avoid the dictionary and create other entities that exposes the foreign keys and relationships (e.g. Tires collection on Bike and FK on Tire), and use a mapping approach like described here.
But I would like to avoid that in my model because it would result in lots of extra classes. But what about performance? Is this worse or the same?
I am no expert at using Dapper but I have run into limitations with it like the one you're experiencing. I had a similar situation where one of the properties in my object was a collection like you tires. I found it was simpler to create a second query to populate those inner types of collections with an extension method.
So you might just grab all the bikes first and then call your extension method to grab the tire data like:
dict.WithTires();
I know its a second call to the database but the tradeoff is that you can still grab a bike without having to get the tires information everytime.
Also, you might think about adding the tires collection as a property to your bike class which IMHO is better than uing a dictionary. If you had something like this:
public class Bike
{
public int id { get; set; }
public string modelName { get; set; }
public IList<Tires> tires { get; set; }
}
public class Tires
{
public int id { get; set; }
public string tread { get; set; }
}
You could easily create an extension method for grabbing the tire data for an individual bike or a collection of bikes:
Bike myBike = new Bike();
List<Bike> bikeCollection = new List<Bike>();
myBike.WithTires();
bikeCollection.WithTires();
I have two tables having 1 to 1 relationship. One table called Person and second is PersonDetails. PesonId is in PersonDetails table as FK.
I can query individual tables like
public static Person GetPersonById(int personId)
{
using (var context = new REntities())
{
return context.Person.Where(p => p.PersonId == personId).First();
}
}
It is being used in consuming code like:
Person personInfo = PersonService.GetPersonById(personId);
and same with PersonDetail on its PK i.e. PersonDetailId
But when I have to fetch data from two tables then I am not understanding that what how would I do this and what would be the best way to return data to presentation layer.
Following would be the code to get Person and relate PersonDetails records:
from personData in context.person.Include("PersonDetail")
where personData.PersonId == personId
select personData;
What is personData here?
How can I iterate over it and get each item in client code?
Thanks.
When you get your Person object, you can include the PersonDetails object as well within the query like this...
using (var context = new REntities())
{
return context.Person.Include("PersonDetail").Where(p => p.PersonId == personId).First();
}
Now on the presentation side, when you get the Person object, iterate through each item of person detail like this...
from p in personInfo.PersonDetails
select p; // here p is the person detail object
Hope it helps.
If you are using Entity Framework Code First (EF 4.1), mark the PersonDetails property in the Person class as virtual. This will enable EF to populate the data automatically so you can simply do person.PersonDetails to get your list of data