I am trying to create custom tables for Identity Authentication, but I keep getting this error no matter how many times I have tried to recreate the Identity tables:
The entity types 'BBRoleType' and 'UserRoleType' cannot share table 'UserRoleTypes' because they are not in the same type hierarchy or do not have a valid one to one foreign key relationship with matching primary keys between them.
This is my User tables in the database:
And exported as SQL:
/****** Object: Table [dbo].[User] Script Date: 21/12/2015 18:42:21 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[User](
[Id] [uniqueidentifier] NOT NULL,
[Email] [nvarchar](255) NOT NULL,
[IsConfirmed] [bit] NOT NULL,
[PasswordHash] [nvarchar](500) NULL,
[SecurityStamp] [nvarchar](255) NULL,
[UserName] [nvarchar](255) NOT NULL,
[CreateDate] [datetime] NOT NULL,
[LastOnlineDate] [datetime] NOT NULL,
[BirthDate] [datetime] NULL,
[FacebookAccessToken] [nvarchar](max) NOT NULL,
[FacebookName] [nvarchar](500) NOT NULL,
[FacebookId] [nvarchar](max) NOT NULL,
CONSTRAINT [PK_User] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
/****** Object: Table [dbo].[UserClaim] Script Date: 21/12/2015 18:42:22 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[UserClaim](
[Id] [bigint] NOT NULL,
[UserId] [uniqueidentifier] NOT NULL,
[ClaimValue] [nvarchar](max) NOT NULL,
[ClaimType] [nvarchar](max) NOT NULL,
CONSTRAINT [PK_UserClaim] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
/****** Object: Table [dbo].[UserLogin] Script Date: 21/12/2015 18:42:22 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[UserLogin](
[UserId] [uniqueidentifier] NOT NULL,
[ProviderKey] [nvarchar](max) NOT NULL,
[LoginProvider] [nvarchar](max) NOT NULL,
[UserLoginId] [uniqueidentifier] NOT NULL,
CONSTRAINT [PK_UserLogin] PRIMARY KEY CLUSTERED
(
[UserLoginId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
/****** Object: Table [dbo].[UserRole] Script Date: 21/12/2015 18:42:22 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[UserRole](
[RoleId] [uniqueidentifier] NOT NULL,
[UserId] [uniqueidentifier] NOT NULL
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[UserRoleType] Script Date: 21/12/2015 18:42:22 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[UserRoleType](
[Id] [uniqueidentifier] NOT NULL,
[Name] [nvarchar](255) NOT NULL,
CONSTRAINT [PK_UserRoleType] PRIMARY KEY CLUSTERED
(
[Id] 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].[User] ADD CONSTRAINT [DF_User_IsConfirmed] DEFAULT ((0)) FOR [IsConfirmed]
GO
ALTER TABLE [dbo].[UserLogin] ADD CONSTRAINT [DF_UserLogin_UserLoginId] DEFAULT (newid()) FOR [UserLoginId]
GO
ALTER TABLE [dbo].[UserRoleType] ADD CONSTRAINT [DF_UserRoleType_Id] DEFAULT (newid()) FOR [Id]
GO
ALTER TABLE [dbo].[UserClaim] WITH CHECK ADD CONSTRAINT [FK_UserClaim_User] FOREIGN KEY([UserId])
REFERENCES [dbo].[User] ([Id])
GO
ALTER TABLE [dbo].[UserClaim] CHECK CONSTRAINT [FK_UserClaim_User]
GO
ALTER TABLE [dbo].[UserLogin] WITH CHECK ADD CONSTRAINT [FK_UserLogin_User] FOREIGN KEY([UserId])
REFERENCES [dbo].[User] ([Id])
GO
ALTER TABLE [dbo].[UserLogin] CHECK CONSTRAINT [FK_UserLogin_User]
GO
ALTER TABLE [dbo].[UserRole] WITH CHECK ADD CONSTRAINT [FK_UserRole_User] FOREIGN KEY([UserId])
REFERENCES [dbo].[User] ([Id])
GO
ALTER TABLE [dbo].[UserRole] CHECK CONSTRAINT [FK_UserRole_User]
GO
ALTER TABLE [dbo].[UserRole] WITH CHECK ADD CONSTRAINT [FK_UserRole_UserRoleTyp] FOREIGN KEY([RoleId])
REFERENCES [dbo].[UserRoleType] ([Id])
GO
ALTER TABLE [dbo].[UserRole] CHECK CONSTRAINT [FK_UserRole_UserRoleTyp]
GO
After creating the table, I have added a ADO.NET Data Entity Model for the database.
I have created these classes to map to the custom Identity classes:
public class BBUserLogin : IdentityUserLogin<Guid> { }
public class BBUserRole : IdentityUserRole<Guid> { }
public class BBRoleType : IdentityRole<Guid,BBUserRole> { }
public class BBUserClaim : IdentityUserClaim<Guid> { }
public class BBUser : IdentityUser<Guid, BBUserLogin, BBUserRole, BBUserClaim>
{
public DateTime CreateDate { get; set; }
public DateTime LastOnlineDate { get; set; }
public DateTime? BirthDate { get; set; }
public string FacebookAccessToken { get; set; }
public string FacebookName { get; set; }
public string FacebookId { get; set; }
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<BBUser, Guid> manager)
{
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
userIdentity.AddClaim(new Claim(TCCustomClaimTypes.FirstName, this.FacebookName.SubstringUpToFirst(' ')));
return userIdentity;
}
}
And then setup my DbContext as this:
public class ApplicationDbContext : IdentityDbContext<BBUser, BBRoleType, Guid, BBUserLogin, BBUserRole, BBUserClaim>
{
public ApplicationDbContext() : base("MyIdentityConnection")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.HasDefaultSchema("dbo");
modelBuilder.Entity<BBUser>().ToTable("User");
modelBuilder.Entity<BBUserClaim>().ToTable("UserClaim");
modelBuilder.Entity<BBUserLogin>().ToTable("UserLogin");
modelBuilder.Entity<BBUserRole>().ToTable("UserRole");
modelBuilder.Entity<BBRoleType>().ToTable("UserRoleType");
modelBuilder.Entity<BBUser>().Property(x => x.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<BBUserClaim>().Property(x => x.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<BBRoleType>().Property(x => x.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
}
Not that I think i matters, but I am using Guid/[uniqueidentifier] as Ids where I can (the places where the generic TKey is used). The IdentityUserClaim does not allow to change the Id-type, so I am using a bigint for that. Not that I think it matters :-)
I have been banging my head against the wall the entire day with this problem, but I can't figure out what I have done wrong.
It looks to me that the key names Id, Id, UserId, and RoleId need to have proper naming. Can you change the key 'Id' to 'UserId' on the 'User' table? Drop the Id key on UserClaim table. Change 'Id' on UserRoleType table to RoleId.
I think that will fix your issue.
Related
I'm using EF Core 2.2.6 and the schema generated on my local SQL Server 2017 (v14.0) is different from the schema generated on Azure (SQL Server v12.0)
My entity looks like this:
public class MyEntity
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
My DbContext is:
protected override void OnModelCreating(ModelBuilder modelBuilder) {
modelBuilder.Entity<MyEntity>().ToTable("MyTable").HasKey(m => m.Id);
modelBuilder.Entity<MyEntity>().Property(m => m.Name).IsRequired();
}
But the problem is that in the Azure SQL database, the ALLOW_ROW_LOCKS is missing. Why is the generated schema different? Is there a way to force EF to add the ALLOW_ROW_LOCKS = ON (and ALLOW_PAGE_LOCKS = ON)?
CREATE TABLE MyEntity
(
[Id] [UNIQUEIDENTIFIER] NOT NULL,
[Name] [NVARCHAR](MAX) NOT NULL,
[Description] [NVARCHAR](MAX) NULL,
CONSTRAINT [PK_MyEntity]
PRIMARY KEY CLUSTERED ([Id] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
This is how it looks in Azure:
CREATE TABLE MyEntity
(
[Id] [UNIQUEIDENTIFIER] NOT NULL,
[Name] [NVARCHAR](MAX) NOT NULL,
[Description] [NVARCHAR](MAX) NULL,
CONSTRAINT [PK_MyEntity]
PRIMARY KEY CLUSTERED ([Id] ASC)
WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
Actually, if you don't set the ALLOW_ROW_LOCKS = OFF or ALLOW_PAGE_LOCKS = OFF, the table schema will be the same.
No matter in SQL Server or Azure SQL database, both the default value of ALLOW_ROW_LOCKS and ALLOW_PAGE_LOCKS are ON:
Reference: CREATE TABLE (Transact-SQL) :
You said you have the performance problems on Azure SQL database, I agree with Jeroen Mostert that it's not impossible that changing these flags is the solution.
Maybe this document Monitoring and performance tuning can give you more guides to solve the Azure SQL database performance problem.
Hope this helps.
I have a dynamic table in my project, I doing mapping static table by using Nhibernate fluent API in the model solution. Dynamic table going to create at runtime. dynamic tables have dynamic columns. How can I do Create a dynamic table in NHibernate? thanks for help
CREATE TABLE [dbo].[Events](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](max) NULL,
[StartDate] [datetime] NOT NULL,
[EndDate] [datetime] NOT NULL,
[Quota] [int] NOT NULL,
[Description] [nvarchar](max) NULL,
CONSTRAINT [PK_dbo.Events] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
thanks for help.
I was already using Isession.CreateSqlQuery(sql) but not was working Create table
improved when replace code ' Isession.createSqlQuery(sql).executeUpdate()'
I made a left join in linq and the value of UserId is NULLABLE (not in the table) but in the join and visual studio shows this warning.
I think this is a false positive because the code works well when userid is null IsSelected is false.
UserPrivilege class
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
public partial class UserPrivileges
{
public int Id { get; set; }
public int UserId { get; set; }
public int PrivilegeId { get; set; }
public virtual Privileges Privileges { get; set; }
public virtual UserProfile UserProfile { get; set; }
}
The linq query:
using (var dataContext = new MyEntities())
{
List<UserPrivilegesModel> result = (from privileges in dataContext.Privileges
join userPrivileges in dataContext.UserPrivileges on privileges.Id equals userPrivileges.PrivilegeId into tmpUserPrivileges
from userPrivileges in tmpUserPrivileges.DefaultIfEmpty()
//where userPrivileges.UserId == userId
select new UserPrivilegesModel { IsSelected = (userPrivileges.UserId != null), Description = privileges.Description, PrivilegeId = privileges.Id }).ToList();
return result;
}
On Linq userid == null is TRUE
SQL SCRIPT:
GO
/****** Object: Table [dbo].[Privileges] Script Date: 07/12/2016 10:35:21 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Privileges](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](20) NOT NULL,
[Description] [nvarchar](100) NOT NULL,
CONSTRAINT [PK_Privileges] PRIMARY KEY CLUSTERED
(
[Id] 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
/****** Object: Table [dbo].[UserPrivileges] Script Date: 07/12/2016 10:35:21 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[UserPrivileges](
[Id] [int] IDENTITY(1,1) NOT NULL,
[UserId] [int] NOT NULL,
[PrivilegeId] [int] NOT NULL,
CONSTRAINT [PK_UserPrivileges_1] PRIMARY KEY CLUSTERED
(
[UserId] ASC,
[PrivilegeId] 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
/****** Object: Table [dbo].[UserProfile] Script Date: 07/12/2016 10:35:21 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[UserProfile](
[UserId] [int] IDENTITY(1,1) NOT NULL,
[UserName] [nvarchar](56) NOT NULL,
[Enabled] [smallint] NULL,
CONSTRAINT [PK__UserProf__1788CC4CB96C92F3] PRIMARY KEY CLUSTERED
(
[UserId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
CONSTRAINT [UQ__UserProf__C9F28456208EB813] UNIQUE NONCLUSTERED
(
[UserName] 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].[UserPrivileges] WITH CHECK ADD CONSTRAINT [FK_UserPrivileges_Privileges] FOREIGN KEY([PrivilegeId])
REFERENCES [dbo].[Privileges] ([Id])
GO
ALTER TABLE [dbo].[UserPrivileges] CHECK CONSTRAINT [FK_UserPrivileges_Privileges]
GO
ALTER TABLE [dbo].[UserPrivileges] WITH CHECK ADD CONSTRAINT [FK_UserPrivileges_UserProfile] FOREIGN KEY([UserId])
REFERENCES [dbo].[UserProfile] ([UserId])
GO
ALTER TABLE [dbo].[UserPrivileges] CHECK CONSTRAINT [FK_UserPrivileges_UserProfile]
GO
SQL RELATIONSHIP
Should you be checking userPrivlages == null not userPrivlages.UserId == null? Also, should the 2nd from and the join be using the same name?
Try correcting those issues.
The type in the database may be nullable, but the type in the code is not. UserId is of type int, which can never be null. (Hence the error.) So presumably on a class somewhere you have something like this:
public int UserId { get; set; }
To make the type nullable, you would want this:
public int? UserId { get; set; }
Or, if you prefer, this:
public Nullable<int> UserId { get; set; }
This could have implications in other code not shown here about how to use that property, since you're changing the property's type. But this will allow that property to carry a null value.
userPrivaleges.UserId is not nullable, therefore (userPrivalegs.UserId != null) will always be true.
I have 2 tables:
Categories and
Users
The CategoryId is an int and the UserId is a string (nvarchar(128)).
I have this mapping for my user:
this.HasMany(t => t.ForbiddenCategories)
.WithMany(t => t.ForbiddenUsers)
.Map(m =>
{
m.ToTable("UserForbiddenCategories");
m.MapLeftKey("CategoryId");
m.MapRightKey("UserId");
});
but when I create a database for this, it does this:
CREATE TABLE [dbo].[UserForbiddenCategories](
[UserId] [int] NOT NULL,
[CategoryId] [nvarchar](128) NOT NULL,
CONSTRAINT [PK_dbo.UserForbiddenCategories] PRIMARY KEY CLUSTERED
(
[UserId] ASC,
[CategoryId] 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].[UserForbiddenCategories] WITH CHECK ADD CONSTRAINT [FK_dbo.UserForbiddenCategories_dbo.Categories_UserId] FOREIGN KEY([UserId])
REFERENCES [dbo].[Categories] ([Id])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[UserForbiddenCategories] CHECK CONSTRAINT [FK_dbo.UserForbiddenCategories_dbo.Categories_UserId]
GO
ALTER TABLE [dbo].[UserForbiddenCategories] WITH CHECK ADD CONSTRAINT [FK_dbo.UserForbiddenCategories_dbo.IdentityUsers_CategoryId] FOREIGN KEY([CategoryId])
REFERENCES [dbo].[IdentityUsers] ([Id])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[UserForbiddenCategories] CHECK CONSTRAINT [FK_dbo.UserForbiddenCategories_dbo.IdentityUsers_CategoryId]
GO
which is completely the wrong way around. CategoryId should be the int with a FK to Categories and UserId should be the string with a FK to IdentityUsers.
Can anyone tell me what I am doing wrong? Or how I can tell EF to change the maps around?
Cheers,
/r3plica
I am a new ASP.NET developer and I have 2 inputs in a form as DateTimes; StartDate and EndDate. I want to make sure that both of them are within the StartDate and EndDate of the Parent from another table. The logic should be as following:
Check if the StartDate of the items comes before the EndDate.
Check if the StartDate & EndDate of the inserted item is within the range of the StartDate and EndDate in the Customers table
So how can I do this logic?
For your information, I have two tables in the database, namely; Customers and Items.Their schema are:
Customers Table:
CREATE TABLE [dbo].[Customers](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar](50) NULL,
[Job] [varchar](50) NULL,
[StartDate] [datetime] NOT NULL,
[EndDate] [datetime] NOT NULL,
CONSTRAINT [PK_Customers] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Items Table:
CREATE TABLE [dbo].[Items](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar](50) NOT NULL,
[Description] [varchar](50) NULL,
[StartDate] [datetime] NOT NULL,
[EndDate] [datetime] NOT NULL,
[CustomerID] [int] NOT NULL,
CONSTRAINT [PK_Items] PRIMARY KEY CLUSTERED
(
[ID] 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
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[Items] WITH CHECK ADD CONSTRAINT [FK_Items_Customers] FOREIGN KEY([CustomerID])
REFERENCES [dbo].[Customers] ([ID])
GO
ALTER TABLE [dbo].[Items] CHECK CONSTRAINT [FK_Items_Customers]
GO
My C# Code:
protected void btnSubmit_Click(object sender, EventArgs e)
{
DateTime startDate = Convert.ToDateTime(txtStartDate.Text);
DateTime endDate = Convert.ToDateTime(txtEndDate.Text);
if (DateTime.Compare(startDate, endDate) <= 0)
{
using (TestDBEntities1 TEntities = new TestDBEntities1())
{
var newItem = new Item
{
Name = txtName.Text,
Description = txtDesc.Text,
StartDate = startDate,
EndDate = endDate,
CustomerID = Convert.ToInt32(ComboBox1.SelectedValue)
};
TEntities.Items.AddObject(newItem);
TEntities.SaveChanges();
}
lblMessage.Text = "Successfully Added :)";
}
else
{
lblMessage.Text = "Error!!!";
}
}
NOTE: I am using LINQ for querying the database. I am only missing the part of doing the logic for checking if the StartDate & EndDate of the inserted item is within the Dates in the Customers table.
Explanation:
For example, let us assume we have StartDate#1 and EndDate#1 for an item that will be inserted. In the Customers table, I have StartDate#2 and EndDate#2. The logic should do the following:
check if the StartDate#1 comes before EndDate#1
Then, check if StartDate#1 and EndDate#1 are falling within the range of StartDate#2 and EndDate#2