EF 6 Mapping Complex Composite Keys - frameworks

I have the following models
public class Company
{
[Key, Column(Order=0)]
public int Id {get;set;}
public string CompanyCode { get; set; }
public string Name { get; set; }
public virtual ICollection<Account> Accounts { get; set; }
public virtual ICollection<Journal> Journals { get; set; }
}
public class Account
{
[Key, Column(Order=0)]
public int Id { get; set; }
[Key, Column(Order=1), ForeignKey("Company")]
public int CompanyId { get; set; }
public int GLAccountNumber { get; set; }
public decimal Balance { get; set; }
public virtual Company Company { get; set; }
public virtual ICollection<Journal> Journals { get; set; }
}
public class Journal
{
[Key, Column(Order=0)]
public int Id { get; set; }
[Key, Column(Order=1), ForeignKey("Company")]
public int CompanyId { get; set; }
[ForeignKey("Account")]
public int AccountId { get; set; }
public DateTime EntryDate { get; set; }
public decimal Amount { get; set; }
public virtual Company Company { get; set; }
public virtual Account Account { get; set; }
}
How would I map the relationship between these models, Specifically I cannot figure out how to define the Composite Key in the Journal Model to map to Account By CompanyId, AccountId

You could use fluent APi (my personal preference - clear and less error prone):
modelBuilder.Entity<Journal>()
.HasRequired(e => e.Account)
.WithMany(e => e.Journals)
.HasForeignKey(e => new { e.AccountId, e.CompanyId });
But if you prefer data annotations, then apply the ForeignKey attribute on the navigation property and specify comma separated list of the FK properties:
public class Journal
{
[Key, Column(Order=0)]
public int Id { get; set; }
[Key, Column(Order=1)]
public int CompanyId { get; set; }
public int AccountId { get; set; }
public DateTime EntryDate { get; set; }
public decimal Amount { get; set; }
[ForeignKey("CompanyId")]
public virtual Company Company { get; set; }
[ForeignKey("AccountId,CompanyId")]
public virtual Account Account { get; set; }
}

Related

Why does EF.core sometimes includes invalid columns?

How does EF.Core choose it's columns?
I have these two simple classes: Payment and Site
I use this for my select list:
var payments = db.Payments
.Include(e => e.Site)
.AsNoTracking();
EF.Core generates this invalid sql:
SELECT [e].[pay_id], [e].[amount], [e].[cheque_no], [e].[client_id], [e].[dt], [e].[last_modified], [e].[last_modified_by], [e].[pay_dt], [e].[pay_mode], [e].[site_id], [e.Site].[site_id], [e.Site].[address], [e.Site].[client_id], [e.Site].[last_modified], [e.Site].[last_modified_by], [e.Site].[name], [e.Site].[state]
FROM [Payments] AS [e]
INNER JOIN [Sites] AS [e.Site] ON [e].[site_id] = [e.Site].[site_id]
ORDER BY [e.Site].[name]
There is no client_id in the Payments table or Payment class below
public class Payment
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Int32 pay_id { get; set; }
public DateTime? dt { get; set; }
public Int32 site_id { get; set; }
public Decimal? amount { get; set; }
public DateTime? pay_dt { get; set; }
public String pay_mode { get; set; }
public String cheque_no { get; set; }
public virtual Site Site { get; set; }
public DateTime? last_modified { get; set; }
public int? last_modified_by { get; set; }
}
public class Site
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Int32 site_id { get; set; }
public String name { get; set; }
public Int32 client_id { get; set; }
public String address { get; set; }
public String state { get; set; }
public virtual Client Client { get; set; }
public List<Deployment> Deployments { get; set; }
public List<Contract> Contracts { get; set; }
public List<Timesheet> Timesheets { get; set; }
public DateTime? last_modified { get; set; }
public int? last_modified_by { get; set; }
}

Error in creating a controller file

I am using Entity Framework. I have tried everything, searching and adding keys but Ienter image description here cannot understand what the problem is and how to resolve it.
public class Reservation
{
[Key]
public int BookingID { get; set; }
public int CustomerID { get; set; }
public int RoomID { get; set; }
public string BookingDate { get; set; }
public int Check_In { get; set; }
public int Check_Out { get; set; }
public int Adults { get; set; }
public int Children { get; set; }
public int NoOfNights { get; set; }
[ForeignKey("RoomID")]
public virtual Room Rooms { get; set; }
[ForeignKey("CustomerID")]
public virtual CustomerDetails CustomerDetail { get; set; }
public virtual ICollection<Payment> Payment { get; set; }
}
public class CustomerDetails
{
[Key]
public int CustomerID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int PostCode { get; set; }
public string State { get; set; }
public int PhoneNumber { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public virtual ICollection<Reservation> Reservations { get; set; }
}
enter image description here
All tables need a primary key or you can't use Entity Framework.

Entity Framework - unwanted population of related entity

Given
public class Customer
{
public int Id { get; set; }
[Required]
[StringLength(255)]
public string Name { get; set; }
[Required]
public DateTime DateOfBirth { get; set; }
public bool IsSubscribed { get; set; }
public MembershipType MembershipType { get; set;}
public byte MembershipTypeId { get; set; }
}
why does
onDb = _context.Customers.Single(c => c.Id == customer.Id);
populate the MembershipType object??? I don't want that to happen.
Is it because I have loaded the customer with the same ID before?

EntityFramework One-To-Many fK?

BasketItem duplicateBasketItem = (from ph in storeDB.BasketItems
where ph.sellerSKU == newItem.sellerSKU
select ph).SingleOrDefault();
{"Invalid column name 'BasketID'."}
My Classes:
public class Basket
{
[Key]
public string BasketID { get; set; }
public virtual IList<BasketItem> BasketItems { get; set; }
public int? Count { get; set; }
public System.DateTime DateCreated { get; set; }
public Guid UserID { get; set; }
}
public class BasketItem
{
[Key]
public int BasketItemID { get; set; }
public virtual string BasketID { get; set; }
[Required]
public int sellerID { get; set; }
[Required]
public string sellerSKU { get; set; }
[Required]
public int Quantity { get; set; }
[Required]
public decimal Price { get; set; }
}
From the research i have done so far, the error is being cause due to relationships not being mapped properly. How would I map the relationship using modelbuilder
Each basket can(optional) contain many basketitems
Each BasketItem has a BaskedID(FK) to map back to the individual Basket.

EF5 CodeFirst + Relationships between non-key columns

In have two classes;
public class Item
{
[Key]
public int Id { get; set; }
[Required]
public string Name { get; set; }
public virtual BinCard BinCard { get; set; }
}
and
public class BinCard
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
public int ItemId { get; set; }
[Required]
public DateTime Date { get; set; }
[Required]
public double Qty { get; set; }
public ObservableCollection<Item> Item { get; set; }
}
The BinCard.Id is the PK and auto increments.
I want the relationship between two tables using Item.Id and BinCard.ItemId using*FluentAPI*.
Please help me to create this relationship correctly.
EF does not support non-PK principal Ids because it doesn't support unique keys other than PKs yet. To make this work you will have to create relationship based on BinCard.Id and BinCardId to Item entity - btw. it looks like the correct way to build relationship in your model. Your current model looks really strange.
Thanks for all replies. This is the solution for my question.
public class BinCard
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
public int ItemId { get; set; }
[Required]
public DateTime Date { get; set; }
[Required]
public double Qty { get; set; }
public virtual Drug Drug { get; set; }
}
public class Item
{
[Key]
public int Id { get; set; }
[Required]
public string Name { get; set; }
public ObservableCollection<BinCard> BinCard { get; set; }
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Drug>()
.HasRequired(s => s.Stock)
.WithRequiredPrincipal(s => s.Drug);
}