I have the following model:
public class Task
{
public int Id { get; set; }
public int UseraccountId { get; set; }
public virtual Useraccount Useraccount { get; set; }
}
The useraccountId is my foreign key showing to my useraccount entity/model.
The entity framework can map this foreign key to the virtual property because it removes the "Id", so "useraccountId" becomes "useraccount" -> mapping to "Useraccount".
What if I want to rename the foreign key "useraccountId" to "creatorId"? How can I now tell the Entity framework to map this foreign key to the virtual Useraccount property?
Use the ForeignKey attribute.
public class Task
{
public int Id { get; set; }
public int CreatorId { get; set; }
[ForeignKey("CreatorId")]
public virtual Useraccount Useraccount { get; set; }
}
Related
I have the following model classes. I want that TripId and TouristId would be a composite key of Attendance entity.
For now I get this error while the sql is executed:
CREATE TABLE [Attendance] (
[Id] int NOT NULL IDENTITY,
[TouristId] nvarchar(450) NOT NULL,
[TripId] int NOT NULL,
CONSTRAINT [PK_Attendance] PRIMARY KEY ([Id]),
CONSTRAINT [FK_Attendance_AspNetUsers_TouristId] FOREIGN KEY ([TouristId]) REFERENCES [AspNetUsers] ([Id]) ON DELETE CASCADE,
CONSTRAINT [FK_Attendance_Trip_TripId] FOREIGN KEY ([TripId]) REFERENCES [Trip] ([Id]) ON DELETE CASCADE);
Introducing FOREIGN KEY constraint 'FK_Attendance_Trip_TripId' on
table 'Attendance' may cause cycles or multiple cascade paths. Specify
ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN
KEY constraints. Could not create constraint or index. See previous
errors.
public class Attendance
{
public virtual Trip Trip { get; set; }
public virtual ApplicationUser Tourist { get; set; }
}
public class ApplicationUser : IdentityUser
{
[PersonalData]
[Column(TypeName = "nvarchar(MAX)")]
public string FirstName { get; set; }
[PersonalData]
[Column(TypeName = "nvarchar(MAX)")]
public string Surname { get; set; }
[PersonalData]
[Column(TypeName = "nvarchar(MAX)")]
public string BirthDate { get; set; }
}
public class Trip
{
public int TripId { get; set; }
public string TripDate { get; set; }
public int TripDuration { get; set; }
public int TripLength { get; set; }
public int TripSeats { get; set; }
public Trail Trail { get; set; }
public ApplicationUser Guide { get; set; }
}
EDIT:
public class Attendance
{
public int AttendanceId { get; set; }
public int? TripId { get; set; }
public int? TouristId { get; set; }
public virtual Trip Trip { get; set; }
public virtual ApplicationUser Tourist { get; set; }
}
But foreign keys are still set as 'NOT NULL'.
In DbContext class into the OnModelCreating overriding do this :
modelBuilder.Entity<Attendance>()
.HasOne(p => p.Tourist)
.WithMany<ApplicationUser>()
.OnDelete(DeleteBehavior.Cascade `or` DeleteBehavior.Restrict);
I have the below domain classes:
public class Product
{
public Guid? Id { get; set; }
public string? Name { get; set; }
}
public class Order
{
public Guid? Id { get; set; }
public string? Address{ get; set; }
public Guid? ProductId{ get; set; }
}
I am not using navigation properties for setting the foreign key but am doing it as below:
public void Configure(EntityTypeBuilder<Order> builder)
{
builder.HasOne<Product>()
.WithMany()
.HasForeignKey(c => c.ProductId);
}
My problem when I do the update-database, it says that the field ProductId does not exist. This is because it named as Id in table product but in table order it is named as ProductId. Is there a way to map the foreign key with a different name?
Modify the Product class
public class Product
{
public Guid? Id { get; set; }
public string? Name { get; set; }
public ICollection<Order> Orders {get; set;}
}
The relationship will work properly.
Reference: Relationships
I have the following models in my .NET Core 2.1 application:
public class Product
{
[Key]
public Guid ProductId { get; set; }
public virtual ICollection<Favourite> Favourites { get; set; }
}
public class Retailer
{
[Key]
public Guid BusinessId {get; set;}
public virtual ICollection<Favourite> Favourites { get; set; }
}
public class Favourite
{
[Key]
public Guid FavouriteId { get; set; }
[ForeignKey("Retailer_BusinessId")]
public virtual Retailer Business { get; set; }
[ForeignKey("Product_ProductId")]
public virtual Product Product { get; set; }
}
When trying to run an EF migration, I get the following error:
The relationship from 'Favourite.Business' to 'Retailer.Favourites'
with foreign key properties {'Retailer_BusinessId' : Nullable}
cannot target the primary key {'BusinessId' : Guid} because it is not
compatible. Configure a principal key or a set of compatible foreign
key properties for this relationship.
I suspect it's because I'm using Guid's as my keys in the foreign tables. How do I tell EF that?
It looks like EF expects the ForeignKey attribute to refer to the navigation property. I was able to reproduce the error you were getting and after making the following change, it migrated successfully.
public class Favourite
{
[Key]
public Guid FavouriteId { get; set; }
[ForeignKey("Business")]
public Guid BusinessId { get; set; }
[ForeignKey("Product")]
public Guid ProductId { get; set; }
public virtual Retailer Business { get; set; }
public virtual Product Product { get; set; }
}
EDIT: The way you were doing it was close, but you need to have the property and then specify just the property's name in the ForeignKey attribute.
public class Favourite
{
[Key]
public Guid FavouriteId { get; set; }
public Guid BusinessId { get; set; }
public Guid ProductId { get; set; }
[ForeignKey("BusinessId")]
public virtual Retailer Business { get; set; }
[ForeignKey("ProductId")]
public virtual Product Product { get; set; }
}
How do I specify a foreign key that references a specific property instead of the primary key?
For example the Stock class has a uuid property. And I want to create a foreign key in the Valuation class that references it using this property.
In the following example the line [ForeignKey(typeof(Stock))] references the ID property of the Stock class, but I need it to reference the UUID property.
How would I do that?
public class Stock
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string UUID { get; set; }
[MaxLength(8)]
public string Symbol { get; set; }
[OneToMany(CascadeOperations = CascadeOperation.All)] // One to many relationship with Valuation
public List<Valuation> Valuations { get; set; }
}
public class Valuation
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
[ForeignKey(typeof(Stock))] // Specify the foreign key
public string StockUUID { get; set; }
public DateTime Time { get; set; }
public decimal Price { get; set; }
[ManyToOne] // Many to one relationship with Stock
public Stock Stock { get; set; }
}
A ForeignKey always references the PrimaryKey of another class. In this case, your PrimaryKey is an integer, but you are trying to reference another property of type string. This is not supported, so you either reference the primary key, or you make the UUID property primary key.
public class Stock
{
[PrimaryKey]
public string UUID { get; set; }
[MaxLength(8)]
public string Symbol { get; set; }
[OneToMany(CascadeOperations = CascadeOperation.All)] // One to many relationship with Valuation
public List<Valuation> Valuations { get; set; }
}
Hello I have table in the database which consist only of foreign keys. This table structure is like below:
Code is generated by VS in Database first :
public partial class DeviceUsage
{
public int StorageId { get; set; }
public int UserId { get; set; }
public int DeviceInstanceId { get; set; }
public virtual DeviceInstance DeviceInstance { get; set; }
public virtual Storage Storage { get; set; }
public virtual User User { get; set; }
}
As You can see all keys are foreign from 3 other tables.
I'm aware that EntityFramework don't like tables without primary keys.
But even that I need to ask you if there is any possibility to make it work or I am forced to add new column Id to my table?
You have to set your primary key.You don't need to add extra Id column, you can set one of those properties as primary key with [Key] attribute. For example:
[Key]
public int StorageId { get; set; }
Looking at this article about Entity Framework and Code First Data Annotations it seems that your answer is
public partial class DeviceUsage
{
[Key]
[Column(Order=1)]
public int StorageId { get; set; }
[Key]
[Column(Order=2)]
public int UserId { get; set; }
[Key]
[Column(Order=3)]
public int DeviceInstanceId { get; set; }
public virtual DeviceInstance DeviceInstance { get; set; }
public virtual Storage Storage { get; set; }
public virtual User User { get; set; }
}
I think that inserting is not possible without primary key.
Just add
[Require]
public int DeviceUsageId {get;set}
and let it be, you dont have to use this PK