I have a class 'BudgetDetail' like this:
public class BudgetDetail
{
public int Id { get; set; }
public Budget Budget{ get; set; }
public int BudgetId { get; set; }
public Product Product { get; set; }
public int ProductId { get; set; }
public byte Quantity { get; set; }
public int Price { get; set; }
public int Iva { get; set; }
public int Total { get; set; }
}
And this is the Fluent API configuration for this model:
public class BudgetDetailConfiguration: EntityTypeConfiguration<BudgetDetail>
{
public BudgetDetailConfiguration()
{
ToTable("BudgetDetails");
HasKey(pd => new { pd.Id, pd.BudgetId, pd.ProductId });
Property(pd => pd.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
}
}
And when I made the migration, the identity of the Id property is setting to true but if I look in the database the identity it is set to false and I don't know why, I guess it is because I have composite keys to this table.
Identity column doesn't work if you have composite keys?
You have a BudgetId and a Budget - same for Product. Adding both does not mean they are related. The Budget object is unrelated to the BudgetId - the BudgetDetails class has two different attributes - one if BudgetId (FK) and one is an actual Budget object.
Remove your objects and keep their PKs - which are FKs within the BudgetDetail class.
public class BudgetDetail
{
public int Id { get; set; }
// public Budget Budget{ get; set; }
public int BudgetId { get; set; }
// public Product Product { get; set; }
public int ProductId { get; set; }
.../...
}
Related
Given two tables, TrackingTag and TrackingTagStatusUpdate:
public class TrackingTag
{
public int ID { get; set; }
}
public class TrackingTagStatusUpdate
{
public int ID { get; set; }
public int TrackingTagID { get; set; }
public TrackingTag TrackingTag { get; set; }
public int Epoch { get; set; } //32-bit
[MaxLength(32)]
public string APConnectedSSID { get; set; }
}
As there will be many TrackingTagStatusUpdates, I want to add a field "LatestStatusUpdate" to TrackingTag, for performance reasons.
public class TrackingTag
{
public int ID { get; set; }
public int? LatestStatusUpdateID { get; set; }
public TrackingTagStatusUpdate LatestStatusUpdate { get; set; }
}
LatestStatusUpdate is optional, as it may not be set if there are not yet any Status Updates for the Tag.
Entity Framework Core complains that "The child/dependent side could not be determined for the one-to-one relationship between 'TrackingTag.LatestStatusUpdate' and 'TrackingTagStatusUpdate.TrackingTag'.". I then add
modelBuilder.Entity<TrackingTag>().HasOne(x => x.LatestStatusUpdate).WithOne(x => x.TrackingTag).HasForeignKey<TrackingTagStatusUpdate>(x => x.TrackingTagID);
to OnModelCreating(ModelBuilder modelBuilder), however this results in Entity Framework Core creating a relationship with a Unique constraint, which will not work as there will be many TrackingTagStatusUpdate with the same TrackingTagID.
How do I do this correctly?
This seems to have worked:
public class TrackingTag
{
public int ID { get; set; }
[ForeignKey(nameof(LatestStatusUpdate))]
public int? LatestStatusUpdateID { get; set; }
public TrackingTagStatusUpdate LatestStatusUpdate { get; set; }
}
I'm not sure how to achieve the same with the Fluent API though.
How can I make the foreign key of a table "PRODUCT" accept null values?
I require that at the time of filling the PRODUCT form you can save the information without having to select the bank. I generate the form PRODUCT(Controller) with entity framework
The foreign key del model Product -> "public int EntidadID { get; set; }"
I have two related models.
public class Product
{
[Key]
public int ProductID { get; set; }
public string NumContrato { get; set; }
public float TasaReal { get; set; }
public decimal Capital { get; set; }
public DateTime FechaValor { get; set; }
public DateTime FechaVencimiento { get; set; }
public int Plazo { get; set; }
public int BankID { get; set; }
public virtual CATbank CATbank { get; set; }
}
public class CATbank
{
[Key]
public int BankID { get; set; }
public string Name { get; set; }
public virtual ICollection<Product> Products { get; set; }
}
Is BankID your foreign key?
If so, in the Product class try changing
public int BankID { get; set; }
to
public int? BankID { get; set; }
and in your database table make sure that the field is nullable.
My data class is
public class Data
{
public int Id { get; set; }
public int LeagueId { get; set; }
public League League { get; set; }
public int HomeTeamId { get; set; }
public virtual Team HomeTeam { get; set; }
public int AwayTeamId { get; set; }
public virtual Team AwayTeam { get; set; }
}
and my team class is
public class Team
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Data> Datas { get; set; }
}
which generates an extra foreign key FK_dbo.Data_dbo.Teams_Team_Id and also and extra column in my Data table.
So my first question is, how that foreign-key was created there?
Can i have two one to many relationships that target at the same table with entity framework?
I need to set both the HomeTeamId and the AwayTeamId in the Data table as one to many relationship
Try:
public class Data
{
public int Id { get; set; }
public int LeagueId { get; set; }
[ForeignKey("LeagueId")] /* Add explicit foreign key data annotations */
public League League { get; set; }
public int HomeTeamId { get; set; }
[ForeignKey("HomeTeamId")]
public virtual Team HomeTeam { get; set; }
public int AwayTeamId { get; set; }
[ForeignKey("AwayTeamId")]
public virtual Team AwayTeam { get; set; }
}
public class Team
{
public Team()
{
this.HomeTeamData = new HashSet<Data>();
this.AwayTeamData = new HashSet<Data>();
}
public int Id { get; set; }
public string Name { get; set; }
[InverseProperty("HomeTeam")]
public virtual ICollection<Data> HomeTeamData { get; set; }
[InverseProperty("AwayTeam")]
public virtual ICollection<Data> AwayTeamData { get; set; }
}
Let me know if this helps.
I suspect you may be hitting the limit of Entity's ability to figure out what you want. You may need to consider using some Entity Annotations to instruct Entity on what you want it to actually do.
I want to implement many one-to-zero-or-one relationships in one entity, but I am having problems getting it to work then generating the migration for it.
public class Invoice
{
public int Id { get; set; }
public int? MorningExpenseId { get; set; }
public int? EveningExpenseId { get; set; }
public Expense MorningExpense { get; set; }
public Expense EveningExpense { get; set; }
}
public class Expense
{
public int Id { get; set; }
public int InvoiceId { get; set; }
public Invoice Invoice { get; set; }
}
modelBuilder.Entity<Invoice>()
.HasOptional<Expense>(p => p.MorningExpense)
.WithRequired(g => g.Invoice);
modelBuilder.Entity<Invoice>()
.HasOptional<Expense>(p => p.EveningExpense)
.WithRequired(g => g.Invoice);
But I am getting an error of Schema specified is not valid. Errors: The relationship '...' was not loaded because the type '...' is not available..
I also was experimenting with using a primary composite key in the ´Expense´ class like:
public enum ExpenseType { Morning, Evening };
public class Expense
{
public int Id { get; set; }
public ExpenseType ExpenseType { get; set; }
public Invoice Invoice { get; set; }
}
But also no luck with getting it to work. How this should be implemented using Fluent API?
In Entity framework, appliation types must match Database types. Relationships must have the virtual keywork.
You must code like this
public class Invoice
{
public int Id { get; set; }
public int MorningExpenseId { get; set; }
public int EveningExpenseId { get; set; }
public virtual Expense MorningExpense { get; set; }
public virtual Expense EveningExpense { get; set; }
}
public class Expense
{
public int Id { get; set; }
public int InvoiceId { get; set; }
public virtual Invoice Invoice { get; set; }
}
This will create two tables "Ingredient" and "Recipe" and an additional table for many-to-many mapping.
public class DC : DbContext {
public DbSet<Ingredient> Ingredients { get; set; }
public DbSet<Recipe> Recipes { get; set; }
}
public class Ingredient {
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Recipe> Recipes { get; set; }
}
public class Recipe {
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Ingredient> Ingredients { get; set; }
}
Question: I want to include additional column "quantity" in the third mapping table that will be created by Entity Framework. How to make that possible? Thanks in advance.
When you've got some extra information, I suspect it won't really count as a mapping table any more - it's not just a many-to-many mapping. I think you should just model it as another table:
public class Ingredient {
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<RecipePart> RecipeParts { get; set; }
}
public class RecipePart {
public int Id { get; set; }
public Ingredient { get; set; }
public Recipe { get; set; }
// You'll want to think what unit this is meant to be in... another field?
public decimal Quantity { get; set; }
}
public class Recipe {
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<RecipePart> Parts { get; set; }
}
So now you don't really have a many-to-many mapping - you have two ordinary many-to-one mappings. Do you definitely need to "ingredient to recipes" mapping exposed in your model at all? If you want to find out all the recipes which use a particular ingredient, you could always do a query such as:
var recipies = DB.Recipies.Where(r => r.Parts
.Any(p => p.Ingredient == ingredient));