Multiple Primary Key with asp .net mvc 3 - sql-server-2005

I'm using asp .net mvc 3, and I have a problem with an entity that contains 2 primary key, when I try to insert data in the table.
public class LineItem
{
[Key]
public int OrderId { get; set;}
[Key]
public int LineNum { get; set;}
public string ItemId { get; set;}
public int Quantity { get; set;}
public decimal UnitPrice { get; set; }
}
when I try to insert I got this error :
Unable to determine composite primary
key ordering for type
'ApplicationMVC3.Models.LineItem'. Use the
ColumnAttribute or the HasKey method
to specify an order for composite
primary keys.
May someone help me please !!

Assuming this is actually a composite key, since you can't have 2 primary keys... The error message tells you exactly what to do, namely add an order. You can do this by adding [Column(Order = 0)] and [Column(Order = 1)] to your key columns.
For your example:
public class LineItem
{
[Key][Column(Order = 0)]
public int OrderId { get; set;}
[Key][Column(Order = 1)]
public int LineNum { get; set;}
public string ItemId { get; set;}
public int Quantity { get; set;}
public decimal UnitPrice { get; set; }
}

Related

Can I reference single foreign key on multiple columns in a table? If yes, how to configure it in Entity Framework core

How can I generate above table like structure using Entity Framework core?
I am using code first approach to generate my tables from domain models which are as follows
public class Contact
{
public int ContactId { get; set; }
public string Email { get; set; }
public string Name { get; set; }
}
public class Company
{
public int CompanyId { get; set; }
public string CompanyName { get; set; }
[ForeignKey("Contact")]
public int FirstContact { get; set; }
[ForeignKey("Contact")]
public int SecondContact { get; set; }
[ForeignKey("Contact")]
public int ThirdContact { get; set; }
public virtual Contact Contact { get; set; }
}
In the company table, I want foreign key on columns 'FirstContact', 'SecondContact', 'ThirdContact' which can refer to Contacts table.
I have also tried Fluent API but no success in same also.
Whenever I am running the add-migration command, I am getting this error:
There are multiple properties with the [ForeignKey] attribute pointing to navigation 'Company.Contact'. To define a composite foreign key using data annotations, use the [ForeignKey] attribute on the navigation.
I would appreciate any help regarding the same.
Thanks.
For multiple Navigation Properties, you need multiple Foreign Keys. EG
public class Company
{
public int CompanyId { get; set; }
public string CompanyName { get; set; }
public virtual Contact FirstContact { get; set; }
public virtual Contact SecondContact { get; set; }
public virtual Contact ThirdContact { get; set; }
}
And let EF Core create shadow properties for your FKs or with Foreign Key properties:
public class Company
{
public int CompanyId { get; set; }
public string CompanyName { get; set; }
public int FirstCotactId {get; set;}
public virtual Contact FirstContact { get; set; }
public int SecondCotactId {get; set;}
public virtual Contact SecondContact { get; set; }
public int SecondCotactId {get; set;}
public virtual Contact ThirdContact { get; set; }
}

Why does Entity Framework create a redundant foreign key?

I have these 3 classes:
public class P
{
[Key]
[Column(Order = 0)]
[Required]
public string PId { get; set; }
}
public class E
{
[Key]
[ForeignKey("P")]
[Column(Order = 0)]
[Required]
public string PId { get; set; }
[Key]
[Column(Order = 1)]
[Required]
public string EId { get; set;
}
public class UF
{
[Key]
[Required]
public string Id { get; set; }
[ForeignKey("E")]
[Column(Order = 0)]
public string PId { get; set; }
[ForeignKey("E")]
[Column(Order = 1)]
public string EId { get; set; }
}
When running Entity Framework code-first, I expect to get something like this in the database:
But what I do get is the above + extra FK to PId:
i.e. in CREATE SCRIPT we get:
IF NOT EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_dbo.UF_dbo.E_PId_EId]') AND parent_object_id = OBJECT_ID(N'[dbo].[UF]'))
ALTER TABLE [dbo].[UF] WITH CHECK
ADD CONSTRAINT [FK_dbo.UF_dbo.E_PId_EId]
FOREIGN KEY([PId], [EId]) REFERENCES [dbo].[E] ([PId], [EId])
ON DELETE CASCADE
GO
But we also get this extra/redundant FK:
IF NOT EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_dbo.UF_dbo.P_PId]') AND parent_object_id = OBJECT_ID(N'[dbo].[UF]'))
ALTER TABLE [dbo].[UF] WITH CHECK
ADD CONSTRAINT [FK_dbo.UF_dbo.P_PId]
FOREIGN KEY([PId]) REFERENCES [dbo].[P] ([PId])
ON DELETE CASCADE
GO
Which results in this error when running the whole CREATE SCRIPT:
Introducing FOREIGN KEY constraint 'FK_dbo.UF_dbo.P_PId' on table 'UF' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
Msg 1750, Level 16, State 0, Line 926
Could not create constraint or index. See previous errors.
The question is why?
your ids name is incorrect.
rename your id like this:
pubilc class P
{
public string Id { get; set; }
}
public class E
{
public string PId { get; set; }
//Entity Framework automatically recognizes it is a foreign key for P Table.
public string Id { get; set; }
//don't use EId , For Primary Key just use Id.
}
public class UF
{
public string Id { get; set; }
public string PId { get; set; }
public string EId { get; set; }
//For Foreign key just use: ClassName + Id
}
The answer was not in the question description unfortunately :/
There was an extra virtual memeber P that caused the extra FK:
//Shouldn't be here
public virtual P P { get; set; }
public virtual E E { get; set; }
Yeah Yeah...

Petapoco can't update with non primary key identity

I am using AspNetIdentity and I have a non primary key column that is an identity auto increment.
[TableName("AspNetUsers")]
[PrimaryKey("Id", autoIncrement = false)]
public class Coach
{
public string Id { get; set; }
public string Email { get; set; }
public string UserName { get; set; }
public bool Active { get; set; }
public bool Admin { get; set; }
public int CoachId { get; set; }
}
How can I change my class definition to set CoachId to autoIncrement is false without it being the primary key? I'm using db.Save to save the object.
I just ended up executing a query!
var query = String.Format("UPDATE AspNetUsers SET Active = '{0}' WHERE Id='{1}'",activeStatus,id);

saving reference using ServiceStack ORMLite

I am using ORMLite as my ORM and I am using it with following structure which contains the foreign key relation ship:
public class Order
{
[AutoIncrement]
public int Id { get; set; }
[Reference]
public Item Item { get; set; }
public string ProUserId { get; set; }
public string Details { get; set; }
}
public class Item
{
[AutoIncrement]
public int Id { get; set; }
public string Description { get; set; }
}
As we can see that Order contains the reference to the Item. In DB Order table has a foreign key called ItemId in the table and I have annotated that key in the design view with [Reference] attribute.
I am trying to save the Order with following code:
var order = new Order
{
Item = new Item
{
Id = 3,
Description = "Something"
},
ProUserId = "kunal#kunal.com",
Details = "fdfsdfsd"
};
Db.Save(order,references:true);
I was hoping that ORMLite would pick up the relationship and with ItemID in the Order table but it did not and it did throw following error instead:
Cannot insert the value NULL into column 'ItemId', table 'WebApp.dbo.Order'; column does not allow nulls. INSERT fails.
I tried changing my schema and addred OrderId column in my Item table with reference there and that works fine. But that is not the correct design. Should I make any changes in my code/schema to support this feature?
You still need to provide the foreign key that OrmLite can use to store the relationship, e.g. either on the Child/ForeignKey table:
public class Order
{
[AutoIncrement]
public int Id { get; set; }
[Reference]
public Item Item { get; set; }
public string ProUserId { get; set; }
public string Details { get; set; }
}
public class Item
{
[AutoIncrement]
public int Id { get; set; }
public int OrderId { get; set; } //Parent Table PK
public string Description { get; set; }
}
Or for 1:1 relationships, can be on the Parent table, e.g:
public class Order
{
[AutoIncrement]
public int Id { get; set; }
[Reference]
public Item Item { get; set; }
public int ItemId { get; set; } //Child Table PK
public string ProUserId { get; set; }
public string Details { get; set; }
}
public class Item
{
[AutoIncrement]
public int Id { get; set; }
public string Description { get; set; }
}

ASP.Net MVC3 SQL Nullable

I'm currently working on an ASP.Net MVC3 project. I have it set up so my sql database creates it's tables based off of classes I've created and I need to know if there's a way to set it so that the variables can be null for example:
public class Cart
{
[Key]
public int RecordId { get; set; }
public string CartId { get; set; }
public int VideoId { get; set; }
public int CandyId { get; set; }
public int Count { get; set; }
public System.DateTime DateCreated { get; set; }
public virtual Video Video { get; set; }
public virtual Candy Candy { get; set; }
}
Is there a way to set the VideoId and Candy Id so that they can be null? The way they're coming up right now is as foreign keys to other tables. Any and all help is highly appreciated.
You can make VideoId and CandyId nullable using the ? symbol:
public int? VideoId { get; set; }
public int? CandyId { get; set; }
You have two options:
1) Declare your properties using int?
public int? VideoId { get; set; }
public int? CandyId { get; set; }
2) Declare your properties using regular int, but handling what should happend when you get a null value.
VideoId = thisMightBeNull ?? 0; //?? means, if the variable is null then use 0
Using the first option has the disadventage that if you want to assign VideoId or CandyId to a new variable it should be int?, and sometimes it gets messy.
With the second option you won't have that problem, but it means you should handle what to assign in that moment (default value).