One-to-one relation + on-to-many relation using same entity - c#

I'm trying to create a customer entity that has multiple contact persons, as well as one primary contact person, but I can't seem to add the migration, as I'm getting the following error:
Unable to determine the relationship represented by navigation property 'ContactPerson.Customer' of type 'Customer'. Either manually configure the relationship, or ignore this property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.
Customer
public class Customer
{
public Guid CustomerId { get; set; }
public string Name { get; set; }
public DateTime CreateDate { get; set; }
public string City { get; set; }
public string Address { get; set; }
// Contact person data
public virtual ContactPerson PrimaryContactPerson { get; set; }
public virtual ICollection<ContactPerson> ContactPersons { get; set; }
}
ContactPerson
public class ContactPerson
{
public Guid ContactPersonId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public virtual Customer Customer { get; set; }
}
I tried adding the foreign keys myself, and annotating the foreign key property with my entity, on both the Customer entity as well as the ContactPerson entity, like this:
public class ContactPerson
{
public Guid ContactPersonId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
[ForeignKey("Customer")]
public Guid CustomerId { get; set; }
public virtual Customer Customer { get; set; }
}
But it doesn't seem to make any difference, I'm still getting the same error. How can it be that EF can't determine the relationship?
I suppose it has something to do with the one-to-one relation simultaneously existing with the one-to-many relation, but I can't seem to wrap my head around this issue. Advice and suggestion are highly appreciated!
If I comment out the PrimaryContactPerson property, EF adds the migration just fine, so I'm positive that this has something to do with the two different relations.

I managed to solve my issue using the Entity Framework Fluent API, like this:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<ContactPerson>(e =>
e.HasOne(r => r.Customer).WithMany(c => c.ContactPersons)
);
}

Related

Entity Framework Code First One Property of Class and List of The Same Class

I'm using entity framework code first approach
I have a class
public class Movie
{
public int Id { get; set; }
public string Title { get; set; }
public Person Director { get; set; }
public virtual ICollection<Person> Actors { get; set; }
}
and a class
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
When the database is created I get one table Movies with Id, Title, Director_Id and a table Person with Id and Name.
I expect to have a table Movies_Persons with columns Movie_Id and Actor_Id
How can I achieve this?
Your Problem is, that you don`t tell the Person Class, that there can be multiple Movies per person.
So by adding the following line in your person class:
public virtual ICollection<Movie> Movies { get; set; }
Your entity knows that both your classes can have multiple references to the other class.
To fulfill this requirement Entity Framework will create a third table with Movie_ID and Person_ID.
If you want more informations just look for:
Entity Framework - Many to many relationship
or follow this link:
http://www.entityframeworktutorial.net/code-first/configure-many-to-many-relationship-in-code-first.aspx
You can check out the other articels on that page too, if you are new to entity framework.
UPDATE:
Sorry i missed, that you are already have another reference to your person table.
Here you have to tell your entity framework, which way you want to reference the two tables by fluent api.
Check out this stackoverflow answer. That should do the trick.
You have to insert this code into your OnModelCreating Function of your DbContext Class.
So your final code should look like this:
public class Movie
{
public int Id { get; set; }
public string Title { get; set; }
public virtual Person Director { get; set; }
public virtual ICollection<Person> Actors { get; set; }
}
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Movie> Movies_Actors { get; set; }
public virtual ICollection<Movie> Movies_Directors { get; set; }
}
And in your OnModelCreating add following code:
modelBuilder.Entity<Movie>()
.HasMany(a => a.Actors)
.WithMany(a => a.Movies_Actors)
.Map(x =>
{
x.MapLeftKey("Movie_ID");
x.MapRightKey("Person_ID");
x.ToTable("Movie_Actor");
});
modelBuilder.Entity<Movie>()
.HasRequired<Person>(s => s.Director)
.WithMany(s => s.Movies_Directors);
I don't have the possibility to test the code, but that should do the trick.
If you have to do some adjustments to make it work, plz add them in the comments, so other ppl can benefit from it.

Adding Extra Column to join table

I currently have an employee model
public string FirstName { get; set; }
public string LastName { get; set; }
public virtual ICollection<StateLicenseType> Licenses { get; set; }
and a License Type Model
public class StateLicenseType
{
public int StateLicenseTypeId { get; set; }
public string State { get; set; }
public string LicenseName { get; set; }
public virtual Employee Employee { get; set; }
}
This relationship can be one to many, but I also need to add some information to the license when saved. I need to be able to store the employees unique license number and have not been able to find out how to do this while searching around. Is there a way to have Entity Framework add a column to a join table and then even if I have to, update it myself?
Is there a better/different way to model this relationship with EF?
In an old DB the table was created like this,
CREATE TABLE `nmlsstatelicenses` ( `peopleid` int(11) DEFAULT NULL, `statelicensetypeid` int(11) DEFAULT NULL, `licensenumber` varchar(25) DEFAULT NULL)
You need to create a third entity which will be a linking entity (like a linking table in many-to-many relationships in database. Here is an example: many-to-many relationships with additional information.
So you would have the following entities in your model:
public Employee
{
public string EmployeeId { get;set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public virtual ICollection<LicenseRegistration> RegisteredLicenses { get; set; }
}
public LicenseType
{
public int StateLicenseTypeId { get; set; }
public string State { get; set; }
public string LicenseName { get; set; }
public virtual ICollection<LicenseRegistration> RegisteredLicenses { get; set; }
}
public LicenseRegistration
{
//properties for the additional information go here
/////////////////////////////////////////////////////
public int EmployeeId {get;set;}
[ForeignKey("EmployeeId")]
public Employee Employee {get;set;}
public int LicenseTypeId {get;set;}
[ForeignKey("LicenseTypeId")]
public LicenseType {get;set;}
}
Then, in your DBContext file, you will need to define 1-to-many relationship between Employee and LicenseRegistration, and between LicenseType and LicenseRegistration.
Hope this helps!
UPDATE
Here is how you would set up the relationships:
modelbuilder.Entity<LicenseRegistration>()
.HasRequired(lr => lr.LicenseType)
.WithMany(lt => lt.RegisteredLicenses)
.HasForeignKey(lr => lr.LicenseTypeId);
modelbuilder.Entity<LicenseRegistration>()
.HasRequired(lr => lr.Employee)
.WithMany(e => e.RegisteredLicenses)
.HasForeignKey(lr => lr.EmployeeId);

asp.net mvc - Inserting multiple records in the third table having foreign keys to parent using entity framework 6

I am trying to learn how to use Entity Framework 6 with an already created database, without creating an .edmx file, i.e, using the DbContext and POCO classes.
These are my model classes:
[Table("Category")]
public class Category
{
[Key]
public long CategoryID { get; set; }
public string CategoryName { get; set; }
}
[Table("RegistrationForm")]
public class RegistrationForm
{
[Key]
public int RegistrationID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int Country { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
}
[Table("RegistrationCategory")]
public class RegistrationCategory
{
[Key]
public long RegistrationCategory { get; set; }
public long RegistrationID { get; set; }//Foreign key to RegistrationID in RegistrationForm table in database
public long CategoryID { get; set; }//Foreign key to CategoryID in Category table in database
}
My DbContext class:
public class MyContext : DbContext
{
public virtual DbSet<RegistrationForm> RegistrationForm { get; set; }
public virtual DbSet<Category> Category { get; set; }
public virtual DbSet<RegistrationCategory> RegistrationCategory { get; set; }
}
Here I want to use the default model builder of DbContext.User can select multiple categories in the registration screen so the RegistrationCategory table will have multiple records for each registration. Therefore RegistrationForm and RegistrationCategory are in a one-to-many relationship.
How to write foreign key mappings between the above mentioned models?
How to bind data from Category table data in the mvc view(listbox) so that we can save one record in RegistrationForm table and multiple records in RegistrationCategory table without using loops (using mappings between the c# models) in Entity Framework 6?
The database schema that you have here is a Many to Many relationship between RegistrationForm and Category, with a join table. The RegistrationCategory Table is not necessary to be modeled in Entity Framework at all. You will need to use Entity Framework Fluent API to generate the correct mappings.
First, your RegistrationForm Table:
public class RegistrationForm
{
[Key]
public int RegistrationID { get; set; }
...
// add a navigation property ICollection<Category> to reference the categories
public virtual ICollection<Category> Categories { get; set; }
}
Next, the Category class:
public class Category
{
[Key]
public int CategoryID { get; set; }
public string CategoryName { get; set; }
//Navigation property to reference the RegistrationForms
public virtual ICollection<RegistrationForm> RegistrationForms { get; set; }
}
next, in your DbContext: note the change in pluralization, and the removal of the RegistrationCategory, you do not need a model class for it at all.
public class MyContext : DbContext
{
public virtual DbSet<RegistrationForm> RegistrationForms { get; set; }
public virtual DbSet<Category> Categories { get; set; }
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<RegistrationForm>()
.HasMany(r => r.Categories)
.WithMany(c => c.RegistrationForms)
.Map(
m =>
{
m.MapLeftKey("RegistrationID");
m.MapRightKey("CategoryID");
m.ToTable("RegistrationCategory");
}
);
}
With this in place, you can now query all the Categories of a RegistrationForm or all the RegistrationForms of a Category.
foreach (var category in registrationForm.Categories)
{
//do whatever with each category
}

C# .NET 4.5 and EF 5 update navigation property (foreign key)

I can't update navigation property
I have two entities: User
public class User : Entity
{
public string Username { get; set; }
public string Password { get; set; }
public int? AddressId { get; set; }
public virtual Address Address { get; set; }
}
And Address
public class Address : Entity
{
public string AddressName { get; set; }
public int UserId { get; set; }
public virtual User User { get; set; }
}
When i am trying to do following:
address.User = user;
address userId updates succesfully, and in commit method, entity state is Modified.
But users AddressId won't update.
Here is my context
public DbSet<User> Users { get; set; }
public DbSet<Address> Addresses { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<User>()
.HasOptional(x=>x.Address)
.WithMany()
.HasForeignKey(x=>x.AddressId)
.WillCascadeOnDelete(false);
base.OnModelCreating(modelBuilder);
}
And i am using unity framework and genereic repository pattern.
I tried to set all properties to virtual but no effect.
I think there is a conception problem here, beyond your foreign key problem.
Why do you refer an AddressId if you have already an Address object in your User class ? It's the same thing for your Address class.
Maybe you should try something like this :
public class User : Entity
{
public string Username { get; set; }
public string Password { get; set; }
public virtual Address Address { get; set; }
}
public class Address : Entity
{
public string AddressName { get; set; }
public virtual User User { get; set; }
}
But just to make it clear, Entity Framework is not a magic wizard (clause to...). With your architecture, you have to manually update BOTH foreign keys (if you want to keep your AddressId and UserId properties).

Entity relationship multiple inheritance issue

I have this entity model:
I want to have a Customer entity, which can be either a Person or an Organization, It can't be both.
As of now I came up with a customer entity which points to both organization and person but with a nullable field (meaning Guid?), which means having a non-mandatory relationship with Person and Organization. Something like:
class Customer
{
public Guid ID { get; set; }
public Guid? RelatedPersonID { get; set; }
public Guid? RelatedOrganizationID { get; set; }
public int CustomerStatus { get; set; }
public bool IsVIP { get; set; }
// ... other customer related properties
public virtual Person RelatedPerson { get; set; }
public virtual Organization RelatedOrganization { get; set; }
}
I'm using entity framework 5, codefirst approach and I haven't created the database yet. I was wondering if there's a better model that meets this requirements.

Categories

Resources