Can't see relationship in database diagram entity framework core - asp.net-core

I am working on ASP.NET Core application which uses Entity framework core. I am using code first approach to create database model. I am trying the get one-to-many relationship (one user can have multiple products) between following two classes but in database diagram, I can not see that relationship.
public class SystemUser : IdentityUser
{
public SystemUser()
{
this.ProductToUser = new HashSet<ProductsToUser>();
}
[StringLength(200)]
[Required]
public string FullName { get; set; }
[Required]
[StringLength(200)]
public string Address { get; set; }
[Required]
public int PinNo { get; set; }
[Required]
public int StateId { get; set; }
[Required]
public int CountryId { get; set; }
[Required]
public DateTime RegisterDate { get; set; }
public virtual ICollection<ProductsToUser> ProductToUser { get; set; }
}
public class ProductsToUser
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
public string UserId { get; set; }
[Required]
public int ProductID { get; set; }
[ForeignKey("UserId")]
public SystemUser SystemUser { get; set; }
}
Below is the screenshot of database diagram.
As you can see in diagram it is not showing relationship. But I am getting foreign key constraint in ProductsToUser table as shown below
How do I resolve this issue?

Related

Can I reference single foreign key on multiple columns in a table? If yes, how to configure it in Entity Framework core

How can I generate above table like structure using Entity Framework core?
I am using code first approach to generate my tables from domain models which are as follows
public class Contact
{
public int ContactId { get; set; }
public string Email { get; set; }
public string Name { get; set; }
}
public class Company
{
public int CompanyId { get; set; }
public string CompanyName { get; set; }
[ForeignKey("Contact")]
public int FirstContact { get; set; }
[ForeignKey("Contact")]
public int SecondContact { get; set; }
[ForeignKey("Contact")]
public int ThirdContact { get; set; }
public virtual Contact Contact { get; set; }
}
In the company table, I want foreign key on columns 'FirstContact', 'SecondContact', 'ThirdContact' which can refer to Contacts table.
I have also tried Fluent API but no success in same also.
Whenever I am running the add-migration command, I am getting this error:
There are multiple properties with the [ForeignKey] attribute pointing to navigation 'Company.Contact'. To define a composite foreign key using data annotations, use the [ForeignKey] attribute on the navigation.
I would appreciate any help regarding the same.
Thanks.
For multiple Navigation Properties, you need multiple Foreign Keys. EG
public class Company
{
public int CompanyId { get; set; }
public string CompanyName { get; set; }
public virtual Contact FirstContact { get; set; }
public virtual Contact SecondContact { get; set; }
public virtual Contact ThirdContact { get; set; }
}
And let EF Core create shadow properties for your FKs or with Foreign Key properties:
public class Company
{
public int CompanyId { get; set; }
public string CompanyName { get; set; }
public int FirstCotactId {get; set;}
public virtual Contact FirstContact { get; set; }
public int SecondCotactId {get; set;}
public virtual Contact SecondContact { get; set; }
public int SecondCotactId {get; set;}
public virtual Contact ThirdContact { get; set; }
}

'FK_Ratings_Users_UserId' on table 'Ratings' may cause cycles or multiple cascade paths

I am trying in .NET EFCore the following Code-First migrations through the entities below
User
[Table("Users")]
public class User
{
[Key]
public int Id { get; set; }
[Required]
[MaxLength(100)]
public string FirstName { get; set; }
[Required]
[MaxLength(100)]
public string LastName { get; set; }
[Required]
[MaxLength(250)]
public string Email { get; set; }
[Required]
[MinLength(8), MaxLength(16)]
public string Password { get; set; }
[Required]
[MinLength(6), MaxLength(15)]
public string Phone { get; set; }
public ICollection<Apartment> Apartments { get; set; }
public ICollection<Rating> Ratings { get; set; }
}
Apartment
[Table("Apartments")]
public class Apartment
{
[Key]
public int Id { get; set; }
[Required]
[MinLength(24), MaxLength(100)]
public string Title { get; set; }
[Required]
[MinLength(24), MaxLength(250)]
public string Address { get; set; }
[Required]
public int Price { get; set; }
[ForeignKey("User")]
public int UserId { get; set; }
public User User {get; set;}
public ICollection<Rating> Ratings { get; set; }
public ICollection<AptCateg> AptsCategs { get; set; }
}
Ratings
[Table("Ratings")]
public class Rating
{
[Key]
public int Id { get; set; }
public int Value { get; set; }
[ForeignKey("Apartment")]
public int ApartmentId { get; set; }
public Apartment Apartment { get; set; }
[ForeignKey("User")]
public int UserId { get; set; }
public User User { get; set; }
}
I use the commands dotnet ef migrations add InitialDatabase but when I try to use dotnet ef database update it throws the following error in cmd, as in the title
'FK_Ratings_Users_UserId' on table 'Ratings' may cause cycles or
multiple cascade paths
I tried adding as in the EFCore tutorial from here the modelBuilder's Cascade behavior but it doesn't work because I am getting the same error. I have also tried doing the answer from here but the implementation for HasRequired isn't working even if try to install EntityFrameworkCore.Tools.
I understand that there is an issue with a circular thingy going on. From my intuition the program doesn't know what to do in the case of deleting a user, if to drop or not its ratings and apartments or some of that sort, and this is why its acting this way but I can't fix the problem.
My question is, how can I solve this issue as I cannot create my database, and thus I cannot continue working on the project.
Thanks!
You'll have to make the user relationship optional on one of the tables like:
public int? UserId { get; set; }
Making the property type nullable tells EF that a cascade delete is not required here.
You are causing a cyclic reference by adding the User and Apartment to the Ratings entity. User and Apartment entities already have a one-to-many relationship to the Ratings collection.
'FK_Ratings_Users_UserId' on table 'Ratings' may cause cycles or
multiple cascade paths
This is how the Ratings entity should look like:
[Table("Ratings")]
public class Rating
{
[Key]
public int Id { get; set; }
public int Value { get; set; }
}

Is it possible to create a Domain Class which has Multiple FK Columns to same PK?

I'm a newbie to designing database.
I have problem how to define a domain class which has multiple foreign keys linked with a same primary key.
Here is my model:
namespace OceanFmsSystem.Domain
{
public class ExportTemplate
{
public int Id { get; set; }
public List<ExportBooking> ExportBookings { get; set; }
public string TemplateName { get; set; }
public int CustomerId { get; set; }
public string Incoterms { get; set; }
public string IncotermsDetail { get; set; }
public string PaymentTerm{ get; set; }
public int CountryOriginId { get; set; }
public int CountryDestinationId { get; set; }
}
}
What I want to do is that CountryOriginId & CountryDestinationId should refer to the below class as foreign keys:
namespace OceanFmsSystem.Domain
{
public class Country
{
public int Id { get; set; }
public string CountryCode { get; set; }
public string CountryName { get; set; }
}
}
As far as I know, in EF Core there is an convention which I should name a foreign key as below for migration from code to database.
public type ClassNameOfPrimaryKeyId { get; set;}
Is there any possible way to make this happens?
Yes, possible. Your class should look like this:
public class ExportTemplate
{
//...
public int CountryOriginId { get; set; }
public Country CountryOrigin { get; set; }
public int CountryDestinationId { get; set; }
public Country CountryDestination { get; set; }
}
EF is smart enough to figure the Ids by convention. If you do not wish to follow the convention you can use [ForeignKey] attribute on the properties to configure the FK:
[ForeignKey("Origin")]
public int MyOriginId { get; set; }
public Country Origin { get; set; }

ASP.NET MVC - Scaffolding a Drop Down List

I'm trying to learn how to use the ASP.NET MVC 4 and Entity FrameWork 5, and I'm a bit confused by scaffolding for Drop Down Lists.
I have three classes:
public class ScopeType
{
public int ScopeTypeId { get; set; }
[Required]
public string Type { get; set; }
}
public class ScopeManufacturer
{
public int ScopeManufacturerId { get; set; }
[Required]
[Display(Name="Manufacturer Name")]
public string Name { get; set; }
}
public class Scope
{
public int ScopeId { get; set; }
[Required]
public ScopeManufacturer ScopeManufacturer { get; set; }
[Required]
public string Name { get; set; }
[Required]
public ScopeType ScopeType { get; set; }
[Required]
public int Aperture { get; set; }
[Required]
public int FocalLength { get; set; }
}
Essentially, the first two classes are just lists of values that I want to appear in the drop downs on the 'Scope' create/edit forms. It's a 1 to 1 relationship.
I build the solution, and then add scaffolded controllers and views. Unfortunately, for the 'Scope' controller and views, the ScopeType and ScopeManufacturer navigation properties are ignored; no drop down lists are generated.
I then found on Google examples where people describe specifying the relationship between items by creating properties of integers, with the same name as the Id on the related thing. Therefore, I deleted the controllers and views, and tried again with:
public class Scope
{
public int ScopeId { get; set; }
[Required]
public int ScopeManufacturerId { get; set; }
[Required]
public string Name { get; set; }
[Required]
public int ScopeTypeId { get; set; }
[Required]
public int Aperture { get; set; }
[Required]
public int FocalLength { get; set; }
}
This still didn't scaffold drop down lists for me - rather, it gave me 2 extra fields for me to type integers into.
What am I doing wrong, or am I mistaken in believing that the scaffolding in MVC 4 will generate drop down lists for 1 to 1 relationships like that?

Joins in Entity Framework 5

I have two classes in my model
[Table("tblPackages")]
public class Packages
{
public int Id { get; set; }
[Required]
[Display(Name = "Package Type")]
public int TypeId { get; set; }
[Display(Name = "No of SMS")]
public int AllowedSMS { get; set; }
[Display(Name = "Time Span in Days")]
public int? TimeSpan { get; set; }
public decimal Price { get; set; }
}
[Table("tblPackageTypes")]
public class PackageTypes
{
public int Id { get; set; }
public string Name { get; set; }
public string Details { get; set; }
public DateTime DueDate { get; set; }
}
and the table is same. now i need to get all from class Packages and just Name from class PackageTypes. How can i do by just using Entity Framework
Add a PackageTypes navigation property to your Packages class and access it by name:
[Table("tblPackages")]
public class Packages
{
public int Id { get; set; }
[Required]
[Display(Name = "Package Type")]
public int PackageTypesId { get; set; }
public PackageTypes PackageTypes { get; get; }
[Display(Name = "No of SMS")]
public int AllowedSMS { get; set; }
[Display(Name = "Time Span in Days")]
public int? TimeSpan { get; set; }
public decimal Price { get; set; }
}
By convention, Entity Framework will match the PackageTypesId and PackageTypes properties based on the naming (although you can use different names if you configure it to do so, but that's a more advanced topic).
Now you can access the Name directly from your Packages objects:
myPackage.PackageTypes.Name
Also, you might want to think about your classes in the singular, not the plural. The class represents a single Package, not the entire collection. Same with the PackageType. It makes your code more understandable:
Package myPackage = new Package();
myPackage.PackageType.Name
Only use plural if your class truly represents the entire collection and not a single item.
Use a navigation property, you will need a FK relationship between Packages and PackageTypes:
[Table("tblPackages")]
public class Packages
{
public int Id { get; set; }
[Required]
[Display(Name = "Package Type")]
public int TypeId { get; set; }
[Display(Name = "No of SMS")]
public int AllowedSMS { get; set; }
[Display(Name = "Time Span in Days")]
public int? TimeSpan { get; set; }
public decimal Price { get; set; }
public int PackageTypesId {get;set;}
public virtual PackageTypes {get;set;}
}
[Table("tblPackageTypes")]
public class PackageTypes
{
public int Id { get; set; }
public string Name { get; set; }
public string Details { get; set; }
public DateTime DueDate { get; set; }
public ICollection<Packages> {get;set;}
}
Like the previous answer states you need a navigation property. From your code I assume TypeId is FK to Id in PackageTypes. If this is so, simply create a property named Type of the type PackageType. When EF finds a navigation property to another entity it tries to find the property with the FK by appending the suffix Id or _Id.
If you on the other want a true composite object joining in fields from several tables you should use a view for this!
Regards
HÃ¥kan