SQLite.Net Extensions with multiple foreign keys - sqlite-net-extensions

I am getting the following error when attempting to create a one-to-many relationship that has a multi value foreign key...
**
SQLite.Net.SQLiteException : foreign key mismatch - "Activity" referencing "Node"
**
This is the table SQL (simplified for clarity)...
CREATE TABLE [Activity] (
[ID] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
[InstId_FK] numeric(18,0) NOT NULL,
[NodeSeq_FK] numeric(3,0) NOT NULL,
[ActivityType] int NOT NULL,
CONSTRAINT [Node_FK] FOREIGN KEY([InstId_FK], [NodeSeq_FK]) REFERENCES [Node]([ID], [NodeSeq])ON DELETE CASCADE);
CREATE TABLE [Node] (
[ID] NUMERIC(18) NOT NULL CONSTRAINT [ID] REFERENCES [Trip]([ID]) ON DELETE CASCADE,
[NodeSeq] numeric(3,0) NOT NULL,
[Status] int,
[Name] nvarchar(30) NOT NULL,
CONSTRAINT [sqlite_autoindex_TripNode_1] PRIMARY KEY ([ID], [NodeSeq]));
And my C# Models (again simplified for clarity)...
public class TripNodeActivity : LocationAware
{
[PrimaryKey, AutoIncrement, ForeignKey(typeof(Node),Order = 1)]
public int Id { get; set; }
[Column("InstId_FK")]
public int InstIdFk { get; set; }
[Column("NodeSeq_FK"), ForeignKey(typeof(Node),Order = 2)]
public int NodeSeqFk { get; set; }
public int ActivityType { get; set; }
}
public class Node
{
public Node(){Activity = new List<Activity>();}
[OneToMany(CascadeOperations = CascadeOperation.All)]
public List<Activity> Activity{get;set;}
[PrimaryKey, ForeignKey(typeof(Trip))]
public int Id { get; set; }
[PrimaryKey]
public int NodeSeq { get; set; }
public int Status { get; set; }
public String Name { get; set; }
}
This error happens when trying to save the model using:
SQLiteConnection.InsertOrReplaceWithChildren(NodeFromAbove,true)

Few things there.
First, you have two PrimaryKey attributes in Node class. That is not supported in SQLite-Net.
Second, you are specifying that the PrimaryKey is also a ForeignKey for another table in both classes. That's not what you want to do.
Probably this is more likely what you were trying:
public class TripNodeActivity : LocationAware
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
[Column("InstId_FK")]
public int InstIdFk { get; set; }
[Column("NodeSeq_FK"), ForeignKey(typeof(Node)]
public int NodeSeqFk { get; set; }
public int ActivityType { get; set; }
}
public class Node
{
public Node(){Activity = new List<Activity>();}
[OneToMany(CascadeOperations = CascadeOperation.All)]
public List<Activity> Activity{get;set;}
[PrimaryKey]
public int Id { get; set; }
public int NodeSeq { get; set; }
public int Status { get; set; }
public String Name { get; set; }
}
Hope it helps.

Related

Error while generating Model in MVC

I got the following error while generating a Model in ASP.Net:
MvcApplication1.Models.Department: : EntityType 'Department' has no key defined. Define the key for the EntityType.
department: EntityType: EntitySet 'department' is based on type 'Department' that has no keys define.
Here's a screenshot with more details:
I added the primary key to the Department table:
{
[Table("department")]
public class Department
{
public int dept id { get; set; }
public string department { get; set; }
public List<Employee> Employees { get; set; }
}
}
You need to add a [key] annotation to your deptid field:
{
[Table("department")]
public class Department
{
[Key]
public int deptid { get; set; }
public string department { get; set; }
public List<Employee> Employees { get; set; }
}
}
department table. ' {
[Table("department")]
public class Department
{
[Key]
public int dept id { get; set; }
public string department { get; set; }
public List<Employee> Employees { get; set; }
}
}`
Add key attribute, refer msdn
Another option is to change public int deptid to either public int Id or public int DepartmentId. This is a built-in EF convention, and if you use this syntax, you don't need the [Key] attribute.
https://msdn.microsoft.com/en-us/library/jj679962(v=vs.113).aspx#Anchor_1

Code First Foreign Key Configuration in Many to Many Relationships

I have created two table.
Table 1: Parent table with ParentId and ParentName fields.In this ParentId is primary key.
Table 2: Child table with ChildId and ChildName fields.In this ChildId is primary key.
I want to get the ParentId and ChildId into another table.So icreated table in the name MappingParentChild with ParentId1,ChildId1.I want this ParentId1 and ChildId1 as foreign key.
How can i achive this.
public class Parent
{
public int ParentId { get; set; } //Primary key
public string ParentName { get; set; }
}
public class Child
{
public int ChildId { get; set; } //Primary key
public string ChildName { get; set; }
}
public class MappingParentChild
{
public int Id { get; set; }
public int ParentId1 { get; set; } // want Foreign key for Parent(ParentId)
public int ChildId1 { get; set; }// want Foreign key for Child(ChildId)
}
public class MappingParentChildConfiguration :EntityTypeConfiguration<MappingParentChild>
{
public MappingParentChildConfiguration()
{
ToTable("MappingParentChild");
Property(m => m.Id).IsRequired();
Property(m => m.ParentId1).IsRequired();
Property(m => m.ChildId1).IsRequired();
}
}
How can i do this.Please help me.
public class Parent
{
public int ParentId { get; set; }
public string ParentName { get; set; }
public virtual ICollection<MappingParentChild> parent{ get; set; }
}
public class Child
{
public int ChildId { get; set; }
public string ChildName { get; set; }
public virtual ICollection<MappingParentChild> child { get; set; }
}
public class MappingParentChild
{
public int Id { get; set; }
public int ParentId1 { get; set; }
public int ChildId1 { get; set; }
public virtual Parent pt{ get; set; }
public virtual Child Ch{ get; set; }
}
public class MappingParentChildConfiguration : EntityTypeConfiguration<MappingParentChild>
{
public MappingParentChildConfiguration()
{
ToTable("MappingParentChild");
Property(m => m.Id).IsRequired();
HasRequired(m => m.pt).WithMany(e => e.parent).HasForeignKey(m => m.ParentId );
HasRequired(m => m.ch).WithMany(e => e.child ).HasForeignKey(m => m.ChildId );
}
}

MVC Code First Entity Frame Work reference same oject twice from master object

Have a code first MVC4 model that requires foreign key look up to the same table. i.e My Project table has two columns (BaseFiscalId and IMITApprovalCycleId) that reference the same table i.e. FiscalYears. How do I define this in the code.
Currently I have the following:
public class Project
{
[Required]
public int Id { get; set; }
[Required]
public int InitiativeId { get; set; }
[Required]
public String ProjectName { get; set; }
[Required]
public int SubPortFolioId { get; set; }
[Required]
public String Description { get; set; }
[Required]
public int ProjectTypeId { get; set; }
[Required]
public int FundingSourceId { get; set; }
[Required]
public int FundingPhaseAId { get; set; }
[Required]
public int ApprovalStatusId { get; set; }
[Required]
public int IMITApprovalProcessId { get; set; }
[Required]
public int IMITApprovalCycleId { get; set; }
[Required]
public int AccountableExecutiveId { get; set; }
[Required]
public int LeadMinistryId { get; set; }
[Required]
public int BaseFiscalId { get; set; }
[Required]
public int TotalSpentToBase { get; set; }
//Navigation Properties --Child Projects
public ICollection<Spend> Spends { get; set; }
public SubPortfolio SubPortfolio { get; set; }
public ProjectType ProjectType { get; set; }
public FundingPhase FundingPhase { get; set; }
public FundingSource FundingSource { get; set; }
public ApprovalStatus ApprovalStatus { get; set; }
public IMITApprovalProcess IMITApprovalProcess { get; set; }
public FiscalYear IMITApprovalCycle { get; set; }
public FiscalYear BaseFiscal { get; set; }
public Portfolio Portfolio { get; set; }
public Executive AccountableExecutive { get; set; }
public Ministry LeadMinistry { get; set; }
public Initiative Initiative { get; set; }
}
FiscalYears Class
public class FiscalYear
{
[ScaffoldColumn(false)]
public int Id { get; set; }
[Required]
public String FiscalYearName { get; set; }
}
This results in the following SQL:
CREATE TABLE [dbo].[Projects] (
[Id] INT NOT NULL,
[InitiativeId] INT NOT NULL,
[ProjectName] NVARCHAR (MAX) NOT NULL,
[SubPortFolioId] INT NOT NULL,
[Description] NVARCHAR (MAX) NOT NULL,
[ProjectTypeId] INT NOT NULL,
[FundingSourceId] INT NOT NULL,
[FundingPhaseAId] INT NOT NULL,
[ApprovalStatusId] INT NOT NULL,
[IMITApprovalProcessId] INT NOT NULL,
[IMITApprovalCycleId] INT NOT NULL,
[AccountableExecutiveId] INT NOT NULL,
[LeadMinistryId] INT NOT NULL,
[BaseFiscalId] INT NOT NULL,
[TotalSpentToBase] INT NOT NULL,
[FundingPhase_Id] INT NULL,
[Portfolio_Id] INT NULL,
[Initiative_Id] INT NULL,
CONSTRAINT [PK_dbo.Projects] PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_dbo.Projects_dbo.SubPortfolios_SubPortFolioId] FOREIGN KEY ([SubPortFolioId]) REFERENCES [dbo].[SubPortfolios] ([Id]) ON DELETE CASCADE,
CONSTRAINT [FK_dbo.Projects_dbo.ProjectTypes_ProjectTypeId] FOREIGN KEY ([ProjectTypeId]) REFERENCES [dbo].[ProjectTypes] ([Id]) ON DELETE CASCADE,
CONSTRAINT [FK_dbo.Projects_dbo.FundingPhases_FundingPhase_Id] FOREIGN KEY ([FundingPhase_Id]) REFERENCES [dbo].[FundingPhases] ([Id]),
CONSTRAINT [FK_dbo.Projects_dbo.FundingSources_FundingSourceId] FOREIGN KEY ([FundingSourceId]) REFERENCES [dbo].[FundingSources] ([Id]) ON DELETE CASCADE,
CONSTRAINT [FK_dbo.Projects_dbo.ApprovalStatus_ApprovalStatusId] FOREIGN KEY ([ApprovalStatusId]) REFERENCES [dbo].[ApprovalStatus] ([Id]) ON DELETE CASCADE,
CONSTRAINT [FK_dbo.Projects_dbo.IMITApprovalProcesses_IMITApprovalProcessId] FOREIGN KEY ([IMITApprovalProcessId]) REFERENCES [dbo].[IMITApprovalProcesses] ([Id]) ON DELETE CASCADE,
**CONSTRAINT [FK_dbo.Projects_dbo.FiscalYears_Id] FOREIGN KEY ([Id]) REFERENCES [dbo].[FiscalYears] ([Id])**,
CONSTRAINT [FK_dbo.Projects_dbo.Portfolios_Portfolio_Id] FOREIGN KEY ([Portfolio_Id]) REFERENCES [dbo].[Portfolios] ([Id]),
CONSTRAINT [FK_dbo.Projects_dbo.Executives_AccountableExecutiveId] FOREIGN KEY ([AccountableExecutiveId]) REFERENCES [dbo].[Executives] ([Id]) ON DELETE CASCADE,
CONSTRAINT [FK_dbo.Projects_dbo.Ministries_LeadMinistryId] FOREIGN KEY ([LeadMinistryId]) REFERENCES [dbo].[Ministries] ([Id]) ON DELETE CASCADE,
CONSTRAINT [FK_dbo.Projects_dbo.Initiatives_Initiative_Id] FOREIGN KEY ([Initiative_Id]) REFERENCES [dbo].[Initiatives] ([Id])
Note instead of creating two FK relationships to FiscalYears One each for BaseFiscal and IMITApprovalCycle it create only on on Fiscal_Id which does not exist in the Projects Table.
Thanks
Craig

Entity Framework Code-First : How to design?

I have a MS-SQL table as shown below.
Users Table
CREATE TABLE [dbo].[Users](
[UserId] [uniqueidentifier] NOT NULL Primary Key,
[UserAccount] [nvarchar](50) NOT NULL Unique,
[Password] [nvarchar](50) NOT NULL,
[UserEmail] [nvarchar](50) NOT NULL,
[JoinDate] [datetime2](7) NOT NULL,
[LoginDate] [datetime2](7) NULL)
Roles Table
CREATE TABLE [dbo].[Roles](
[RoleId] [uniqueidentifier] NOT NULL Primary Key,
[RoleName] [nvarchar](50) NOT NULL Unique,
[Note] [nvarchar](50) NOT NULL,
[RegistDate] [datetime2](7) NOT NULL)
UsersInRoles Table
CREATE TABLE [dbo].[UsersInRoles](
[UserId] [uniqueidentifier] NOT NULL,
[RoleId] [uniqueidentifier] NOT NULL,
[SetDate] [datetime2](7) NOT NULL,
PRIMARY KEY CLUSTERED (
[UserId] ASC,
[RoleId] ASC)WITH (
PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
GO
ALTER TABLE [dbo].[UsersInRoles] WITH CHECK ADD FOREIGN KEY([RoleId]) REFERENCES [dbo].[Roles] ([RoleId]) GO
ALTER TABLE [dbo].[UsersInRoles] WITH CHECK ADD FOREIGN KEY([UserId]) REFERENCES [dbo].[Users] ([UserId]) GO
I'm trying to express in EF Code-First of this.
User Entity Class
public class User
{
public Guid UserId { get; set; }
public string UserAccount { get; set; }
public string Password { get; set; }
public string UserEmail { get; set; }
public DateTime JoinDate { get; set; }
public DateTime LoginDate { get; set; }
}
Role Entity Class
public class Role
{
public Guid RoleId { get; set; }
public string RoleName { get; set; }
public string Note { get; set; }
public DateTime RegistDate { get; set; }
}
UsersInRole Entity Class
public class UsersInRole
{
public Guid UserId { get; set; }
public Guid RoleId { get; set; }
public DateTime SetDate { get; set; }
}
The problem of the foreign key, How should designed UsersInRoles?
Please let me know if there is a better design.
It's not really code first if you are designing your database and then making the code conform, is it? Sounds like you should have a roles collection defined on your User class and then let EntityFramework do the work of building that intermediate table. It will handle the FK relationships.
I haven't tried running the following code, so I aren't 100% sure.
However I would start out with something like ...
in your domain classes
public class User
{
public Guid UserId { get; set; }
public string UserAccount { get; set; }
public string Password { get; set; }
public string UserEmail { get; set; }
public DateTime JoinDate { get; set; }
public DateTime LoginDate { get; set; }
}
public class Role
{
public Guid RoleId { get; set; }
public string RoleName { get; set; }
public string Note { get; set; }
public DateTime RegistDate { get; set; }
}
public class UsersInRole
{
public DateTime SetDate { get; set; }
virtual User User { get; set; }
virtual Role Role { get; set; }
}
in your context you need
public DbSet<Role> Roles { get; set; }
public DbSet<User> Users { get; set; }
public DbSet<UsersInRole> UsersInRoles { get; set; }
optionally you might want to include
public virtual ICollection<UsersInRole> Roles { get; private set; }
in the User class
and/or
public virtual ICollection<UsersInRole> Users { get; private set; }
in the role class
Which will keep the same data structure.

EntityType 'ApplicantPosition' has no key defined

When running my first asp.net mvc application I got this error
I thought that entity framework automatically would create the keys of column names that end with Id? isnt it correct?
As you can see the ApplicantPositionID would be a table with 2 columns as primary key because it would relate to Applicants and also to Position.
One or more validation errors were detected during model generation:
System.Data.Edm.EdmEntityType: : EntityType 'ApplicantImage' has no key defined. Define the key for this EntityType.
System.Data.Edm.EdmEntityType: : EntityType 'ApplicationPositionHistory' has no key defined. Define the key for this EntityType.
System.Data.Edm.EdmEntitySet: EntityType: EntitySet �ApplicantsPositions� is based on type �ApplicantPosition� that has no keys defined.
System.Data.Edm.EdmEntitySet: EntityType: EntitySet �ApplicantImages� is based on type �ApplicantImage� that has no keys defined.
System.Data.Edm.EdmEntitySet: EntityType: EntitySet �ApplicationsPositionHistory� is based on type �ApplicationPositionHistory� that has no keys defined.
The error is thrown in this line:
public ActionResult Index()
{
return View(db.Positions.ToList());
}
And my model is the following one:
namespace HRRazorForms.Models
{
public class Position
{
public int PositionID { get; set; }
[StringLength(20, MinimumLength=3)]
public string name { get; set; }
public int yearsExperienceRequired { get; set; }
public virtual ICollection<ApplicantPosition> applicantPosition { get; set; }
}
public class Applicant
{
public int ApplicantId { get; set; }
[StringLength(20, MinimumLength = 3)]
public string name { get; set; }
public string telephone { get; set; }
public string skypeuser { get; set; }
public ApplicantImage photo { get; set; }
public virtual ICollection<ApplicantPosition> applicantPosition { get; set; }
}
public class ApplicantPosition
{
public int ApplicantID { get; set; }
public int PositionID { get; set; }
public virtual Position Position { get; set; }
public virtual Applicant Applicant { get; set; }
public DateTime appliedDate { get; set; }
public int StatusValue { get; set; }
public Status Status
{
get { return (Status)StatusValue; }
set { StatusValue = (int)value; }
}
//[NotMapped]
//public int numberOfApplicantsApplied
//{
// get
// {
// int query =
// (from ap in Position
// where ap.Status == (int)Status.Applied
// select ap
// ).Count();
// return query;
// }
//}
}
public class ApplicantImage
{
public int ApplicantId { get; private set; }
public byte[] Image { get; set; }
}
public class Address
{
[StringLength(20, MinimumLength = 3)]
public string Country { get; set; }
[StringLength(20, MinimumLength = 3)]
public string City { get; set; }
[StringLength(20, MinimumLength = 3)]
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
}
public class ApplicationPositionHistory
{
public ApplicantPosition applicantPosition { get; set; }
public Status oldStatus { get; set; }
public Status newStatus { get; set; }
[StringLength(500, MinimumLength = 10)]
public string comments { get; set; }
public DateTime dateModified { get; set; }
}
public enum Status
{
Applied,
AcceptedByHR,
AcceptedByTechnicalDepartment,
InterviewedByHR,
InterviewedByTechnicalDepartment,
InterviewedByGeneralManager,
AcceptedByGeneralManager,
NotAccepted
}
}
EF Code First can only infer that a property is a primary key if the property is called Id or <class name>Id (or if it is annotated with the Key attribute).
So you need to extend your e.g. ApplicantImage with an ApplicantImageId or Id property etc.
Edit: An artice about the coneventions: Conventions for Code First
You can add the [Key] atributte to the property ApplicantId or do it via Fluent API overriding OnModelCreating method DbContext
modelBuilder.Entity<ApplicantImage >().HasKey(p => p.ApplicantId);
In your case, EF naming convention first looks for an ID (case-insensitive) column. If nothing, looks for ApplicantImageId and when it founds nothing, it raises that error.
So, you should add the [Key] attribute on your ID:
public class ApplicantImage
{
[Key]
public int ApplicantId { get; private set; }
public byte[] Image { get; set; }
}
and if ApplicantId column is identity in your database, you should add another attribute too:
public class ApplicantImage
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int ApplicantId { get; private set; }
public byte[] Image { get; set; }
}
I know this is an old question but it is still relevant. I ran into the same situation however we use a .tt file to generate the .cs from our edmx. Our .tt is setup to add the [Key] attribute on our first column of the table for most situations, but in my case i was using a row over () in SQL to generate unique id's for the first column (works great for most situations). The problem with that was it makes a nullable and the .tt wasn't setup to add [Key] in this case.
Wrapping the row Over() in a ISNULL ((),0) was able to fix making the column not null and solved my problem. Otherwise, as mentioned by marianosz, simply using the .HasKey() in your data context will work fine too.

Resources