I have the following model:
I want to expose a member on "intallations" that give me a list of "modules" based on the join table "installation_modules", how can I do that ?
I want to be able to write
installations.Modules.Something()
Without having to use the join table in my code.
I also want to map "installation_type" directly on the installation, is it possible ? If yes how ?
Entity Framework will automatically manage the many-many relationship for you, but usually the installation_modules table should be having just two columns, installation_id and module_id which will be the composite primary key instead of a separate primary key. So Installation model/class will have public virtual ICollection<Module> Modules {get; set;} and the Module class will have public virtual ICollection<Installation> Installations {get; set;}navigational properties for easy accessing of entities.
I also want to map "installation_type" directly on the installation, is it possible ? If yes how ?
Yes, it is possible. You can have a navigational property for InstallationType in your Installation entity for this.
public class Installation
{
//....other properties
[Column("installation_type_id")]
public int InstallationTypeId {get; set;}
[ForeignKey("InstallationTypeId")]
public virtual InstallationType InstallationType{get; set;}
}
Related
I have a class as
public class fooClass
{
[Key]
public virtual fooRefClass staff { get; set; }
public Int64 fooProp1{ get; set; }
public DateTime fooProp2{ get; set; }
}
when i do the migration it give me error as "no key defined" but i had added the key attonation already .My intention is to make the referenced entity "fooRefClass " as primary key as well as foreign key, i know there is a way by mentioning the attribute id of the referenced entity and writing the foreign-key annotate over there, but i want to deal with entity directly ,rather than id only, how can i attain this functionality ,please help me with the issue.
Since there seems to be confusion, I decided to write an answer as well.
With the class you defined, EF would expect a table like
fooClass(bigint fooRefClass_Id, bigint fooProp1, datetime fooProp2);
... which is not valid, because this has no key column (the key annotation on your navigation property does nothing, because you see, it won't appear in the table... it will just tell EF there is a relationship to this table, and because you didn't provide a FK, it creates one to create this relationship). You also can't create this relationship yourself in your current model, because you don't even have a FK... how would you access a property you know nothing about, just that it will be created at some point (usually upon model creating with first accessing the database).
You have to tell EF you want the property, that will be created, to also be a key, not only a foreign key. You can do this by simply creating the property yourself and telling EF you want to use this, for example (I'm not too familiar with Data Annotations, I usually use Fluent API, so please excuse maybe occuring errors)
[Key, Foreign Key(fooRefClass)]
public Int64 StaffId {get; set;}
In my app I want to have two different types of users. This types differ not only in role but also in attributes. I am using simpleMembership for userManagement and I want to ask what's the best way or practise to create data model for my situation in EF using code first. I was thinking about creating two another tables UsersType1 and UsersType2 which will have one to one relationship with table userProfiles so in the model I would have:
public class UserType1{
attr1
attr2
....
public int userProfileID {get; set;}
public virtual UserProfile userProfile {get; set;}
}
And same way for table UserType2.
I want to ask if this is a good way to go and if so, how should I modify userProfiles table to be able to access UserType1 and UserType2 through userprofile in code.
Thank you.
Use "Roles" to group users of the same type. Then use a custom table with the roleid as key.
I guess you could use inheritance, so UserType1 would inherit from UserProfile.
public class UserType1 : UserProfile
{
attr1
attr2
}
and when you fetch the UserProfile from the database you should be able to cast it to a UserType1 to access the attributes.
I am trying to configure my model to an existing database, and am running into a problem. The previous developer modeled a one-to-one relationship using a join table. If I have the following classes and database structure below, how can I map this using code first?
public class Title {
public Property Property { get; set; }
}
public class Property {
public Title TitleInsurance { get; set; }
}
tbTitle
-TitleID = PK
tbPropertyToTitle
-TitleID - FK to tbTitle.TitleID
-PropertID - FK to tbProperty.PropertyID
tbProperty
-PropertyID = PK
Code in VB.Net here, but should be easy to translate. Mark primary keys with the Key data attribute. Entity Framework will automatically look for properties named Class + ID, i.e. tbTitleID to assign as primary keys, but since that isn't applicable here, we need the Key attribute.
Overridable properties denote Navigation Properties. In C#, this should be equivalent to Virtual properties. When this navigation property is accessed, Entity Framework will automatically look for valid foreign key relations, and populate the appropriate data.
For a one-to-one relationship, Entity Framework expects that your two tables share the same primary key, as shown by TitleID here.
Public Class tbTitle
<Key()>
Public Property TitleID As Integer
...
Public Overridable Property Property As tbProperty
End Class
Public Class tbProperty
<Key()>
Public Property TitleID As Integer
...
Public Overridable Property Title As tbTitle
End Class
Looking through the fluent API, I don't see any way to map one to one relations through a join table. You might be able to fake it by setting it up as a many to many but then you would need a bit of extra code to ensure that your relation collections only ever have one item in them.
I have and EMDX created with Database first, i have followed the sample described here, so now i can map one entity to multiple tables in my database, and this is working fine.
But i need also to have the navigation properties that the FKs provide on the tables on this one entity, how could i achieve that?
I have two tables, on named Carteira and another named Ativo, in my EMDX i want to have the properties of Ativo also to be on Carteira, because they have an 0:1 relationship, so i have done this already and it is working! :) but i also want the navigation properties that are in the Ativo class to be on Carteira
Please see a sample describing the properties :
class Ativo
{
public string Id { get; set; }
public IList<Valor> Valores { get; set; }
}
class Carteira
{
public string AtivoID { get; set; }
public Ativo Ativo {get; set;}
}
So i would like to have something like
Carteira.Valores (and this should be infereed from Ativo).
Please note that i dont want to make this code manually using a partial class and acessing the navitation, i have already done this and i dont like this approach, it looks like this:
public partial class Carteira
{
public List<Valor> Valores
{
get
{
if (this.Ativo == null)
return null;
return this.Ativo.Valores;
}
}
}
I would like to know how to achieve this using the EMDX only, the same way that can be done for simple properties, is this possible?
For 0:1 to 1 relation,EF requires Foreign key to be same as Primary key on dependent table. So Ativo class must have Primary key of same name as AtivoID and that should be foreign key as well.
I managed to get the navigations working in 2 differente ways:
1 - Creating an 'Association' at the model (EMDX).
The associations work as if they were actual FKs, and since i already have the mapping collumns on both sides, it can be done by performing those steps:
Create a new Association at Carteira (second level class) that reflects the same properties of the FK present at Ativo (first level). When this is done, the navigation properties are created on both classes
2- Using Table-Per-Type Inheritance
In this specific scenario, the class could actually inherit from the other, and then take use of all of the navigations, for this to work i had to implement a TBT inheritance, altering the tables and adding "Conditional Mapping" to both tables (the concrete and the inherited) at the model (EDMX)
I have two entities: Recipe and Ingredient.
Entites:
public class Ingredient
{
public int IngredientId{get;set;}
public string Name {get;set;}
public virtual ICollection<Recipe> Recipies {get;set;}
}
public class Recipe
{
public int RecipeId{get;set;}
public string Name {get;set;}
public virtual ICollection<Ingredient> Ingredients {get;set;}
}
My two entities map to their respective tables in the "Web" schema in our database:
ToTable( "Recipe", "Web" );
ToTable( "Ingredient", "Web" );
... and everything works fine. The only hiccup is that the generated many-to-many table is created in the "dbo" schema.
dbo.RecipeIngredients
Without defining the relationships in the Fluent API, is there a way to specify "Web" as the table schema to use for the many-to-many tables?
No. Data annotations support only basic subset of mapping features. If you want to have full code first mapping feature set you must use Fluent API (which is also much cleaner way to define mapping). Defining anything related to junction table is considered as advanced mapping feature and it is currently available only in Fluent API.