I am developing asp.net MVC3 application and I have following entity
This entity has composite key (CreditRegistryId and Accoubnt No are primary keys). CreditRegistryId is a foreign key as well. How can I make composite key and foreign key. I am using DbContext API from EF 4.1. I am not using edmx ( ORM designer)
[Table("tbaAccount")]
public class Account
{
[Column(Name="Creditor Registry ID")] // PK FK
public int CreditRegistryId {get;set;}
[Column(Name = "[Account No]")] //PK
public int AccountNo { get; set; }
[Column(Name = "[Date Opened]")]
public DateTime DateOpened { get; set; }
[ForeignKey("tblAccountStatus")]
[Required]
[Column(Name = "Account Status ID")] // FK
public int AccountStatusId { get; set; }
[Required]
[Column(Name = "Date First Reported")]
public DateTime DateFirstReported { get; set; }
[Required]
[Column(Name = "Credit Limit")]
public double CreditLimit { get; set; }
[Required]
public double Balance { get; set; }
}
and other entity lets say is
public class CreditRegistry
{
public int CreditRegistryId {get;set;}
}
EF does not support associations that use only one property of the ones that participate in a composite key.
Not sure if this scenario can be implemented.
Related
Whenever I am creating a database and feeding on startup(without migrations) It has triggered an error that says
The relationship from 'OrderProducts.Product' to 'Product' with foreign key properties {'IDProduct' : int} cannot target the primary key {'IDProduct' : Guid} because it is not compatible. Configure a principal key or a set of compatible foreign key properties for this relationship
and I cant seem to find a way to correctly configure that the foreign keys are also primary key on this table
public class OrderProducts
{
[ForeignKey("IDProduct")]
public virtual Producto Product {get;set;}=
[ForeignKey("IDOrder")]
public virtual Orden Orden {get;set;}
}
public class Product
{
[Required]
[Key]
public Guid IDProduct { get; set; }
[Required]
[MaxLength(200, ErrorMessage = "Name cant exceed 500 chars")]
public string Name{ get; set; }
[Required]
[Column(TypeName = "decimal(29, 2)")]
[Range(typeof(decimal),"0", "79228162514264337593543950335", ErrorMessage = "Price Limit between 0 - 79228162514264337593543950335")]
public decimal Price{ get; set; }
[Required]
public ProductTypeEnum ProductType { get; set; }
[MaxLength(200, ErrorMessage = "Name cant exceed 500 chars")]
public string Description{ get; set; }
[Required]
public ulong Stock{ get; set; }
[Required]
public string PhotoPath{ get; set; }
[Required]
public Gender Gender {get;set;}
[Required]
public TallasDeProductoEnum Talla {get;set;}
[Required]
public Guid Code{ get; set; }
}```
```cs
public class Order
{
[Key]
public Guid IDOrder { get; set; }
[Required]
public ulong Qty {get;set;}
[ForeignKey("IDClient")]
public virtual Client Client { get; set; }
//public virtual List<Product> Productos {get;set;}
public decimal Total { get; set; }
public DateTime Date{get;set;}
public string IdPayment {get;set;}
public PaymentTypeEnum PaymentType {get;set;}
//public List<OrdenProductos> OrderProducts { get; set; }
}
in AppDbContext
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<OrdenProductos>
().HasKey(nameof(Producto.IDProducto),nameof(Orden.IDOrden));
modelBuilder.Entity<SEOModel>().HasNoKey();
base.OnModelCreating(modelBuilder);
modelBuilder.Seed();
}
what i want to do is a many to many relationship to create a database without any migration but i need to select these columns are PK and FK at the same as a kind of lookup table for orders
public class OrderProducts
{
[ForeignKey("IDProduct")]
public virtual Producto Product {get;set;}
[ForeignKey("IDOrder")]
public virtual Orden Orden {get;set;}
}
public class Order
{
[Key]
public Guid IDOrder { get; set; }
...
}
public class Product
{
[Required]
[Key]
public Guid IDProduct { get; set; }
...
}
The relationship from 'OrderProducts.Product' to 'Product' with
foreign key properties {'IDProduct' : int} cannot target the primary
key {'IDProduct' : Guid} because it is not compatible. Configure a
principal key or a set of compatible foreign key properties for this
relationship
The error message is clear, by using the Fluent API to configure the primary key, it will generate a primary key with int type, but in the Order and Product class, we can see the primary key is the Guid type, so it will show the above not compatible error.
To the this issue, you can set the foreign key data type in the OrderProducts class, like this:
public class OrderProducts
{
public Guid IDProduct { get; set; }
[ForeignKey("IDProduct")]
public virtual Product Product { get; set; }
public Guid IDOrder { get; set; }
[ForeignKey("IDOrder")]
public virtual Order Orden { get; set; }
}
I'm having trouble with my code-first approach to Entity Framework (6) in a project. I effectively have a database that I am attempting to write code that will cause Entity Framework to replicate. I've gotten close so far, but not 100%. The first issue is many-to-many relationship:
I have a base class called Consumer and it has just basic properties:
public abstract class Consumer
{
public Guid ID { get; set; }
[DataType(DataType.DateTime)]
public DateTime CreateDate { get; set; }
[DataType(DataType.DateTime)]
public DateTime? LastModDate { get; set; }
public int RecordStatus { get; set; }
}
I then want to use inheritance for the subsequent classes:
public class Entity : Consumer
{
[DisplayName("Entity Name")]
public string EntityName { get; set; }
[DisplayName("Phone Number"]
public string PhoneNumber { get; set; }
[DisplayName("Doing Business As"]
public string DBA { get; set; }
}
In my context class, I successfully map all of the properties to the table:
modelBuilder.Entity<Entity>().Map(m =>
{
m.MapInheritedProperties();
m.ToTable("Entity");
});
I continued this design with other classes (contacts for example):
public class Contact : Consumer
{
[DisplayName("First Name")]
public string FirstName { get; set; }
[DisplayName("Last Name"]
public string LastName { get; set; }
}
Now, obviously, a contact could be related to more than one Entity and an Entity could be related to more than one Contact. How would I code this? Only thing I could think of was to create a related class like so:
public class RelatedContact
{
public Guid ID { get; set;}
public Guid ContactID { get; set; }
public virtual Contact Contact { get; set; }
public Consumer Parent { get; set; }
public virtual Consumer Parent { get; set; }
public Guid RelationshipTypeID { get; set; }
public virtual RelationshipType RelationshipType { get; set; }
}
Then after creating the related class, I was assuming I needed to go update my Entity class like so:
public class Entity : Consumer
{
[DisplayName("Entity Name")]
public string EntityName { get; set; }
[DisplayName("Phone Number"]
public string PhoneNumber { get; set; }
[DisplayName("Doing Business As"]
public string DBA { get; set; }
public virtual ICollection<Contact> Contacts { get; set; }
}
Then, I would update my DbContext to map the many relationship, but I don't know the correct syntax or if this is even the correct way to approach this. I am trying to get the following tables to output:
<<Entity>>
ID uniqueidentifier,
CreateDate datetime,
LastModDate datetime,
RecordStatus int,
EntityName varchar(250),
PhoneNumber varchar(100),
DBA varchar(250)
<<Contact>>
ID uniqueidentifier,
CreateDate datetime,
LastModDate datetime,
RecordStatus int,
FirstName varchar(100),
LastName varchar(100)
<<RelatedContact>>
ID uniqueidentifier,
ContactID uniqueidentifier,
ParentID uniqueidentifier,
RelationshipTypeID uniqueidentifier
So, any suggestions? Am I at least headed in the right direction?
To create a many-to-many relationship, you need to use second approach. Just add navigation collection to your Entity and Contact classes. And EF will create linking table for you and track links.
public class Entity : Consumer
{
... your props
public virtual ICollection<Contact> Contacts { get; set; }
}
public class Contact : Consumer
{
... your props
public virtual ICollection<Entity> Entities { get; set; }
}
I am working with an existing database where no foreign keys are defined. I can't change the database but would like to define relationships in my entity model. For example, the People table has all the names of the people but the Coaches table only has a reference to the PeopleId. I would like to define that relationship in my Coaches entity object.
I turns out that with more testing it doesn't seem to matter that the database has not defined the foreign key. I'm still able to bring in the associated tables info. Additional testing will be needed because referential integrity is not enforced by the database. However with this table definition and model definition, my person data is being brought in.
[Key]
public int CoachID { get; set; }
public Nullable<int> CompanyID { get; set; }
public Nullable<int> SeasonID { get; set; }
public int PeopleID { get; set; }
public Nullable<int> PlayerID { get; set; }
public string ShirtSize { get; set; }
public string CoachPhone { get; set; }
public Nullable<System.DateTime> CreatedDate { get; set; }
public string CreatedUser { get; set; }
public virtual Person Person { get; set; }
modelBuilder
.Entity<Coach>()
.ToTable("Coaches")
.HasRequired(p => p.Person)
Question 1.
I have created a database in code-first.
[Column(TypeName="datetime2")]
public DateTime RegistDate { get; set; }
In this way, the table is not created.
modelBuilder.Entity<Test>().Property(f => f.RegistDate).HasColumnType("datetime2");
(In OnModelCreating method)
I can be resolved by using Fluent API.
To create a column format datetime2, is there a way only a Fluent API?
Question 2.
I have a domain model as follows.
User Entity Class
public class User
{
public Guid UserId { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public string UserEmail { get; set; }
public DateTime JoinDate { get; set; }
public DateTime LoginDate { get; set; }
public virtual ICollection<UsersInRole> UsersInRoles { get; set; }
}
Role Entity Class
public class Role
{
public Guid RoleId { get; set; }
public string RoleName { get; set; }
public DateTime CreateDate { get; set; }
public virtual ICollection<UsersInRole> UsersInRoles { get; set; }
}
UsersInRole Entity Class
public class UsersInRole
{
public Guid UserId { get; set; }
public Guid RoleId { get; set; }
public DateTime SetDate { get; set; }
[ForeignKey("UserId")]
public User User { get; set; }
[ForeignKey("RoleId")]
public Role Role { get; set; }
}
This build, the following error will occur
One or more validation errors were detected during model generation:
\tSystem.Data.Entity.Edm.EdmEntityType: : EntityType 'UsersInRole' has no key defined. Define the key for this EntityType.
\tSystem.Data.Entity.Edm.EdmEntitySet: EntityType: EntitySet 'UsersInRoles' is based on type 'UsersInRole' that has no keys defined.
I do not want to add another property Id.
Also, I can not use the [Key] UserId, to RoleId.
There are no other solutions?
I'm experimenting with Entity Framework 4 Code First.
I have my (simplified) models set up like this.
public class Entry
{
public int Id { get; set; }
[Required]
public virtual EntryTag Tag { get; set; }
[Required]
public int TagId { get; set; }
[Required]
public string UserId { get; set; }
}
public class EntryTag
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
public string Color { get; set; }
[Required]
public string UserId { get; set; }
}
The user can create a new Entry, and in the same time create or re-use an EntryTag. I try to find an already existing EntryTag based on the name and userId.
var tag = ResolveTag(entry.Tag.Name, entry.UserId);
entry.Tag = tag == null ? AddTagBasedOn(entry) : tag;
_entryRepository.Add(entry);
Now when I find an existing EntryTag, I set it to the Tag property of the Entry. But instead of reusing the EntryTag, the EntryTag gets added (!). I hoped EF would just use the Id to fill in the foreign key? Or am I missing a convention/configuration here?
Thanks