Surrogate Composite Key in MVC 5 - c#

In ASP.NET MVC 5, I have the following models:
JoinModel.cs
// Many-to-many join model
public class JoinModel
{
[Key]
[Column(Order = 0)]
public int ModelAID { get; set; }
[Key]
[Column(Order = 1)]
public int ModelBID { get; set; }
public virtual ModelA ModelA { get; set; }
public virtual ModelB ModelB { get; set; }
public virtual ICollection<ValueModel> Values{ get; set; }
}
ValueModel:
public class ValueModel
{
public int ID { get; set; }
// public int JoinModelID { get; set; }
[DefaultValue(0)]
public int Value { get; set; }
public virtual JoinModel JoinModel { get; set; }
}
I want change it in such a way that I have an ID property in JoinModel, so I can use JoinModelID in ValueModel. I also want to keep ModelAID and ModelBID as composite surrogate/candidate keys (just for uniqueness) and ID as primary key. Is there a way to do so?
Note: making all three ID, ModelAID and ModelBID as composite ID is not what I want.

Related

Mapping self-referencing table data into another model (no automapper is used)

I have this table using Entity Framework code first approach :
public class WebsitePart
{
public WebsitePart()
{
SubParts = new HashSet<WebsitePart>();
}
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public Nullable<int> ParentId { get; set; }
[StringLength(100)]
[Index("UQ_WebsitePart_Key", IsUnique = true)]
public string Key { get; set; }
public virtual WebsitePart Parent { get; set; }
public virtual ICollection<WebsitePart> SubParts { get; set; }
}
I need after getting the list of WebsiteParts to map it into List of another model where each element of this list has ParentId=null and down to the end of its grandsons(traversing) .
This the model I want to map to:
public class WebPartViewDto
{
public int Id { get; set; }
public string Key { get; set; }
public IList<WebPartViewDto> SubWebParts { get; set; }
}
Could you please show me how to map it with performance is taken into account?

Linq Grouping based on other keys and values table

I have two Entities ItemChange and PK:
[Table("Sync_Changes")]
public class ItemChange
{
public Guid AgentId { get; set; }
public DateTime ChangeTime { get; set; }
[Required]
public string Descriminator { get; set; }
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public Guid ID { get; set; }
[NotMapped]
public object Item { get; set; }
public virtual ICollection<PK> PKs { get; set; }
public virtual ChangeType State { get; set; }
}
And the PK class:
[Table("Sync_PKs")]
public class PK
{
public PK(string key, object value)
{
Key = key;
Value = value?.ToString();
ValueType = value?.GetType().Name;
}
[Key]
[Column(Order = 0)]
[ForeignKey(nameof(Change))]
public Guid ChangeId { get; set; }
[Key]
[Column(Order = 1)]
public string Key { get; set; }
[Required]
public string Value { get; set; }
[Required]
public string ValueType { get; set; }
public virtual ItemChange Change { get; set;
}
I want to group the ItemsChange based on the PKs, for example i have two ItemChange that have the Pks [({Key="Id",Value="1"},{Key="GroupId",Value="2"})]
and the ChangeType [Created,Updated].
i want to know how to do this with Linq, or Mysql Script.
Screenshots of the both tables:
Changes that i want to group theme base on the pks.
PKs

The number of properties in the Dependent and Principal Roles in a relationship constraint must be identical?

ConsumerNM is a NM/bridge table/entity.
Its a 1:N relation to Events table.
When I do an insert I get the question title exception.
What do I have to change to make it work?
DO I have to create 2 foreign keys each one pointing to the other ConsumerNM_Key?
public class ConsumerNM
{
public ConsumerNM()
{
Events = new HashSet<Event>();
}
[Key]
[Column(Order = 0)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int FK_LEADMETA { get; set; }
[Key]
[Column(Order = 1)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int FK_LEADCONSUMER { get; set; }
public virtual ICollection<Event> Events { get; set; }
}
public class Event
{
[Key]
public int Id { get; set; }
public DateTime EventDate { get; set; }
public virtual ConsumerNM Consumer { get; set; }
[ForeignKey("Consumer")]
public int FK_Consumer { get; set; }
}
ConsumerNM or Event are incorrect. You have two options:
First Option:
public class ConsumerNM
{
//This is not a PK
//[Key]
//[Column(Order = 0)]
//[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int FK_LEADMETA { get; set; }
[Key]
public int FK_LEADCONSUMER { get; set; }
}
Event remains unchanged.
Second Option:
public class Event
{
[Key]
public int Id { get; set; }
public DateTime EventDate { get; set; }
public virtual ConsumerNM Consumer { get; set; }
[ForeignKey("Consumer")]
public int FK_LEADCONSUMER { get; set; }
[ForeignKey("Consumer")]
public int FK_LEADMETA { get; set; }
}
ConsumerNM remains unchanged.

How to define non mandatory record that has composite key

I have 3 models: Order, Organisation and OrderOrganisation.
Order will always exist, as will Organisation, but OrderOrganisation's existence is not mandatory.
One order can relate to many organisations, and this is the record that will header that information.
I can't change the database structure.
Here are my models.
public class Order
{
public int Id { get; set; }
public virtual ICollection<OrderOrganisation> OrderOrganisations { get; set; }
}
public class Organisation
{
public int Id { get; set; }
public virtual ICollection<OrderOrganisation> OrderOrganisations { get; set; }
}
public class OrderOrganisation
{
[Key, Column(Order = 0)]
public int OrderId { get; set; }
[Key, Column(Order = 1)]
public int OrganisationId { get; set; }
[ForeignKey("OrderId")] //this is not right, i get an inner join not an outer join
public virtual Order Order { get; set; }
[ForeignKey("OrganisationId")] //this is not right, i get an inner join not an outer join
public virtual Organisation Organisation { get; set; }
}
I know I need to add something to the context but I can't work out what?
Thanks
//try this
public class Order
{
[Key]
public int Id { get; set; }
public virtual ICollection<OrderOrganisation> OrderOrganisations { get; set; }
}
public class Organisation
{
[Key]
public int Id { get; set; }
public virtual ICollection<OrderOrganisation> OrderOrganisations { get; set; }
}
public class OrderOrganisation
{
[ForeignKey("Order"), Column(Order = 0)]
public int? OrderId { get; set; }
[ForeignKey("Organisation"), Column(Order = 1)]
public int? OrganisationId { get; set; }
[ForeignKey("OrderId")]
public virtual Order Order { get; set; }
[ForeignKey("OrganisationId")]
public virtual Organisation Organisation { get; set; }
}

Entity Framework table relations

Introduction
I am new to Entity Framework
I am using Code-first
Use-case
I have to following tables
[Table("TBL_UserVariant")]
public class UserVariant
{
[Key, Column(Order = 0)]
public int UserId { get; set; }
[Key, Column(Order = 1)]
public int VarId { get; set; }
public string Value { get; set; }
}
[Table("TBL_UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string eMail { get; set; }
}
I want TBL_UserProfile to refer a list of all TBL_UserVariant entries where TBL_UserProfile::UserId == TBL_UserVariant::UserId
The following is an example of my aim
[Table("TBL_UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string eMail { get; set; }
public UserVariant[] variants;
}
Where 'UserProfile::variants' should include a list of items where 'TBL_UserProfile::UserId == TBL_UserVariant::UserId'
Question
Is this directly possible using EF ? OR, should I implement a wrapper populating 'UserProfile::variants' ~manually~ ?
You have to just add a navigation property to the UserProfile entity.
[Table("TBL_UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string eMail { get; set; }
public virtual ICollection<UserVariant> UserVariants { get; set; }
}
The following is what you should need. EF will take care of the rest.
[Table("TBL_UserProfile")]
public class UserProfile
{
[Key]
public int UserId { get; set; }
public string eMail { get; set; }
public virtual ICollection<UserVariant> Variants { get; set; }
}
[Table("TBL_UserVariant")]
public class UserVariant
{
[Key]
public int VarId { get; set; }
public UserProfile User { get; set; }
public string Value { get; set; }
}
I think what you're asking for is that you want to have one UserProfile, mapped to Many UserVariants
In that case you'll need to add a collection to your UserProfile class.
public virtual ICollection<UserVariant> UserVariants { get; set; }
You'll also need to fix the [Key] property on the UserVariant class as I believe it should be on VarId. You can then just specify a navigation property
[Key]
public int VarId { get; set; }
public UserProfile User { get; set; }
Edit
As an aside, your naming conventions are all over the place. Don't prefix your table names with TBL_. Capitalise all your properties/Columns. e.g. Email not eMail

Categories

Resources