IdentityServer3 with EntityFramework - entity-framework

I hope this is something simple and easy to solve.
I have installed IdentityServer3 in an existing project and managed to get the "in memory" stuff working.
Now I am hooking up to my UserManager. When I try to authenticate, I get this error:
"One or more validation errors were detected during model generation:\r\n\r\nCormar.Sql.Claim: : EntityType 'Claim' has no key defined. Define the key for this EntityType.\r\nCormar.Sql.ClaimsIdentity: : EntityType 'ClaimsIdentity' has no key defined. Define the key for this EntityType.\r\nCormar.Sql.IdentityReference: : EntityType 'IdentityReference' has no key defined. Define the key for this EntityType.\r\nCormar.Sql.Secret: : EntityType 'Secret' has no key defined. Define the key for this EntityType.\r\nCormar.Sql.RefreshToken: : EntityType 'RefreshToken' has no key defined. Define the key for this EntityType.\r\nCormar.Sql.Token: : EntityType 'Token' has no key defined. Define the key for this EntityType.\r\nCormar.Sql.Scope: : EntityType 'Scope' has no key defined. Define the key for this EntityType.\r\nCormar.Sql.ScopeClaim: : EntityType 'ScopeClaim' has no key defined. Define the key for this EntityType.\r\nClaims: EntityType: EntitySet 'Claims' is based on type 'Claim' that has no keys defined.\r\nClaimsIdentities: EntityType: EntitySet 'ClaimsIdentities' is based on type 'ClaimsIdentity' that has no keys defined.\r\nIdentityReferences: EntityType: EntitySet 'IdentityReferences' is based on type 'IdentityReference' that has no keys defined.\r\nSecrets: EntityType: EntitySet 'Secrets' is based on type 'Secret' that has no keys defined.\r\nRefreshTokens: EntityType: EntitySet 'RefreshTokens' is based on type 'RefreshToken' that has no keys defined.\r\nTokens: EntityType: EntitySet 'Tokens' is based on type 'Token' that has no keys defined.\r\nScopes: EntityType: EntitySet 'Scopes' is based on type 'Scope' that has no keys defined.\r\nScopeClaims: EntityType: EntitySet 'ScopeClaims' is based on type 'ScopeClaim' that has no keys defined.\r\n"
I thought this might be because I was missing a package, so I used NuGet to install IdentityServer3.EntityFramework but this didn't work.
Does anyone know how to solve this issue?

This was straight forward enough, you do have to have IdentityServer3.EntityFramework. I looked at the source and saw the migration classes, so I just simply added the entities to my DbContext like this:
public DbSet<Client> Clients { get; set; }
public DbSet<ClientClaim> ClientClaims { get; set; }
public DbSet<ClientSecret> ClientSecrets { get; set; }
public DbSet<Consent> Consents { get; set; }
public DbSet<Scope> Scopes { get; set; }
public DbSet<ScopeClaim> ScopeClaims { get; set; }
Then I did a add-migration and update-database. This created the tables for me and everything was tickity-boo

Related

Can I have an self referencing inverse navigation property with optional foreign key?

ASP.NET Identity developers should recognize my renamed ApplicationUser class (now called User) derived from IdentityUser which has a Guid-based Id property. In my User class I have an optional self referencing foreign key (public Guid? ManagerId) and one simple matching navigation property (public User Manager). All that works. My problem is I want a second navigation property (DirectlyManagedUsers) and I can't figure out how to annotate it such that it will contain a collection of this User's directly managed users. I'd appreciate some help.
Here is my User class:
public class User : IdentityUser
{
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<User> manager, string authenticationType)
{
var userIdentity = await manager.CreateIdentityAsync(this, authenticationType);
return userIdentity;
}
public User() : base()
{
DirectlyManagedUsers = new List<User>();
}
public User(string userName) : base(userName)
{
DirectlyManagedUsers = new List<User>();
}
[ForeignKey(nameof(Manager))]
public Guid? ManagerId { get; set; }
[ForeignKey(nameof(ManagerId))]
public User Manager { get; set; }
[InverseProperty(nameof(Manager))]
public ICollection<User> DirectlyManagedUsers { get; set; }
}
I'm getting the following error on model generation:
One or more validation errors were detected during model generation:
User_DirectlyManagedUsers_Source_User_DirectlyManagedUsers_Target: : The types of all properties in the Dependent Role of a referential constraint must be the same as the corresponding property types in the Principal Role. The type of property 'ManagerId' on entity 'User' does not match the type of property 'Id' on entity 'User' in the referential constraint 'User_DirectlyManagedUsers'. The type of property 'ManagerId' on entity 'User' does not match the type of property 'Id' on entity 'User' in the referential constraint 'User_DirectlyManagedUsers'.
I know that has to do with the nullable Guid type of the ManagerId. So what do I do?
Okay, I figured out what was going wrong. I was using a nullable Guid (Guid?) as the type of my ManagerId. Actually in the ASP.NET Identity framework, the prebuilt Entity Framework IdentityUser class uses a string type for its Id property. This string property is set to the value of a new Guid converted to a string using .ToString(). Once I figured that out (and since I know that string is nullable) I simply changed the type of my ManagerId property to string and everything worked. So my problem was addressed by figuring out the right type in the Identity framework, not by annotating the property a different way for the Entity Framework. I am curious if anyone could answer the original question if the Id was not a nullable type.

Code first migration - sub-class requires Id field

I have a standard MVC 5 project in VS 2013 and using the built-in Identity provider. I am trying to customize the user profile according to http://blogs.msdn.com/b/webdev/archive/2013/10/16/customizing-profile-information-in-asp-net-identity-in-vs-2013-templates.aspx.
I did not expand on ApplicationUser as in the article as I wanted to work on the extension in another project in the same solution. I created a new sub-class ExtendedUser:
public class ExtendedUser : IdentityUser
{
[MaxLength(12)]
public string PIN { get; set; }
}
I then have:
public class UsersContext : DbContext
{
public DbSet<ExtendedUser> ExtendedUsers { get; set; }
public UsersContext() : base() { }
public UsersContext(string ConnectionString) : base(ConnectionString) { }
}
When UsersContext is instantiated and initialized, I get hit by:
System.Data.Entity.ModelConfiguration.ModelValidationException was unhandled by user code
HResult=-2146233088
Message=One or more validation errors were detected during model generation:
IdentityUserLogin: : EntityType 'IdentityUserLogin' has no key defined. Define the key for this EntityType.
IdentityUserRole: : EntityType 'IdentityUserRole' has no key defined. Define the key for this EntityType.
IdentityUserLogins: EntityType: EntitySet 'IdentityUserLogins' is based on type 'IdentityUserLogin' that has no keys defined.
IdentityUserRoles: EntityType: EntitySet 'IdentityUserRoles' is based on type 'IdentityUserRole' that has no keys defined.
....
It seems like the other Identity membership tables are updated, but I did not touch any of those. Why is this happening and how do I correct it.
Try IdentityDbContext<ExtendedUser> as your base class for UsersContext as it is in the post you have mentioned. Without it you don't have any line of code to tell ef which property is the key. If you don't want IdentityDbContext you should in method void OnModelCreating(DbModelBuilder modelBuilder) put property mapping, something like:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<ExtendedUser>().HasKey(t => t.Id);
...
}

Collection of IdentyUsers in EntityFramework - has no key defined

All works well till i decide to add IdentityUser collection in another entity as navigation property.
One or more validation errors were detected during model generation:
IdentityUserLogin: : EntityType 'IdentityUserLogin' has no key defined. Define the key for this EntityType.
IdentityUserRole: : EntityType 'IdentityUserRole' has no key defined. Define the key for this EntityType.
IdentityUserLogins: EntityType: EntitySet 'IdentityUserLogins' is based on type 'IdentityUserLogin' that has no keys defined.
IdentityUserRoles: EntityType: EntitySet 'IdentityUserRoles' is based on type 'IdentityUserRole' that has no keys defined.
But they are part of Microsoft.AspNet.Identity.EntityFramework library. How is it that they has no keys defined???
My entities and db context (EF v6.1, AspNet.Identity v.2.0):
public class User : IdentityUser
{
public virtual int OrganizationId { get; set; }
public virtual Organization Organization { get; set; }
}
public class Organization
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual ICollection<User> Users { get; set; }
}
public class DatabaseModelContext : IdentityDbContext<User>
{
public DatabaseModelContext() : base("ConnectionString") { }
public DbSet<Organization> Organizations { get; set; }
}
Also tried to define explicit relations:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Organization>()
.HasMany(o => o.Users)
.WithOptional(u => u.Organization)
.HasForeignKey(u => u.OrganizationId);
modelBuilder.Entity<User>()
.HasOptional(u => u.Organization)
.WithMany()
.HasForeignKey(u => u.OrganizationId);
}
NO success!!!
It cant just be, that one must define key types for entity framework internal classes!!!
SOLUTION (update)
Actually my simplified example not reflecting my real app situation. My apologies.
I've been using multiple Dbcontexts in my app and organization entity come from separate context what derives form Dbcontext class. In that way this context know nothing about IdentityUser models but Organization entity involves User entity - there is a problem.
Solution - i derived all my other context from IdentityDbContext !!!
Actually my simplified example not reflecting my real app situation. My apologies. I've been using multiple Dbcontexts in my app and organization entity come from separate context what derives form Dbcontext class. In that way this context know nothing about IdentityUser models but Organization entity involves User entity - there is a problem.
Solution - i derived all my other context from IdentityDbContext !!!

Faking Entity Framework and attempting to LINQ query it gives error

We have been trying to figure out how to fake the DbContext. So we followed the example here
http://romiller.com/2012/02/14/testing-with-a-fake-dbcontext/
And the code (one for the abstraction layer over EF (error below) and one directly using EF (works fine)...
All I can figure is maybe this has to do with the abstracted objects over top of the pre generated EF objects do not have a concept of relationship between tables/entities?? any idea?
We have just been trying to find some way to have a common path for our fakes and the real code.. maybe the easy answer is to stop doing it this way and just mock calls to the repository and then unit tests after that point ?
CongressContext context = new CongressContext();
var repo = new CongressRepository(context);
// IEnumerable<tMember> members = repo.Get100MembersDirectEF();
IEnumerable<tMember> members = repo.Get100Members();
..............
public class CongressRepository : ICongressRepository
{
ICongressContext db;
CongressDb_DevEntities realDb = new CongressDb_DevEntities();
public CongressRepository()
{
this.db = new CongressContext();
}
public CongressRepository(ICongressContext context)
{
this.db = context;
}
public List<tMember> Get100Members()
{
var members = db.Members.Where(x => x.MembersID < 100).ToList();
return members;
}
public List<tMember> Get100MembersDirectEF()
{
realDb.Configuration.LazyLoadingEnabled = false;
var members = realDb.tMembers.Where(x => x.MembersID < 100).ToList();
return members;
}
{"One or more validation errors were detected during model generation:\r\n\r\nCongress.Data.tEducationType: : EntityType 'tEducationType' has no key defined. Define the key for this EntityType.\r\nCongress.Data.tCongress: : EntityType 'tCongress' has no key defined. Define the key for this EntityType.\r\nCongress.Data.tCongressMemPositionReason: : EntityType 'tCongressMemPositionReason' has no key defined. Define the key for this EntityType.\r\nCongress.Data.tReasonType: : EntityType 'tReasonType' has no key defined. Define the key for this EntityType.\r\nCongress.Data.tDistrict: : EntityType 'tDistrict' has no key defined. Define the key for this EntityType.\r\nCongress.Data.tParty: : EntityType 'tParty' has no key defined. Define the key for this EntityType.\r\nCongress.Data.tPosition: : EntityType 'tPosition' has no key defined. Define the key for this EntityType.\r\nCongress.Data.tChamber: : EntityType 'tChamber' has no key defined. Define the key for this EntityType.\r\nCongress.Data.tState: : EntityType 'tState' has no key defined. Define the key for this EntityType.\r\nCongress.Data.tMemMilitary: : EntityType 'tMemMilitary' has no key defined. Define the key for this EntityType.\r\nCongress.Data.tMemOccupation: : EntityType 'tMemOccupation' has no key defined. Define the key for this EntityType.\r\nCongress.Data.tOccupationType: : EntityType 'tOccupationType' has no key defined. Define the key for this EntityType.\r\nCongress.Data.tInterestGroup: : EntityType 'tInterestGroup' has no key defined. Define the key for this EntityType.\r\nCongress.Data.tRaceType: : EntityType 'tRaceType' has no key defined. Define the key for this EntityType.\r\nCongress.Data.tReligion: : EntityType 'tReligion' has no key defined. Define the key for this EntityType.\r\ntEducationTypes: EntityType: EntitySet 'tEducationTypes' is based on type 'tEducationType' that has no keys defined.\r\ntCongresses: EntityType: EntitySet 'tCongresses' is based on type 'tCongress' that has no keys defined.\r\ntCongressMemPositionReasons: EntityType: EntitySet 'tCongressMemPositionReasons' is based on type 'tCongressMemPositionReason' that has no keys defined.\r\ntReasonTypes: EntityType: EntitySet 'tReasonTypes' is based on type 'tReasonType' that has no keys defined.\r\ntDistricts: EntityType: EntitySet 'tDistricts' is based on type 'tDistrict' that has no keys defined.\r\ntParties: EntityType: EntitySet 'tParties' is based on type 'tParty' that has no keys defined.\r\ntPositions: EntityType: EntitySet 'tPositions' is based on type 'tPosition' that has no keys defined.\r\ntChambers: EntityType: EntitySet 'tChambers' is based on type 'tChamber' that has no keys defined.\r\ntStates: EntityType: EntitySet 'tStates' is based on type 'tState' that has no keys defined.\r\ntMemMilitaries: EntityType: EntitySet 'tMemMilitaries' is based on type 'tMemMilitary' that has no keys defined.\r\ntMemOccupations: EntityType: EntitySet 'tMemOccupations' is based on type 'tMemOccupation' that has no keys defined.\r\ntOccupationTypes: EntityType: EntitySet 'tOccupationTypes' is based on type 'tOccupationType' that has no keys defined.\r\ntInterestGroups: EntityType: EntitySet 'tInterestGroups' is based on type 'tInterestGroup' that has no keys defined.\r\ntRaceTypes: EntityType: EntitySet 'tRaceTypes' is based on type 'tRaceType' that has no keys defined.\r\ntReligions: EntityType: EntitySet 'tReligions' is based on type 'tReligion' that has no keys defined.\r\n"}
Try it this way, instead of worrying about faking the context, fake the repository.
Real repository will be like this:
public class CongressRepository : ICongressRepository
{
ICongressContext db;
CongressDb_DevEntities realDb = new CongressDb_DevEntities();
public CongressRepository()
{
this.db = new CongressContext();
}
public CongressRepository(ICongressContext context)
{
this.db = context;
}
public List<tMember> GetMembers()
{
realDb.Configuration.LazyLoadingEnabled = false;
var members = realDb.tMembers.Where(x => x.MembersID < 100).ToList();
return members;
}
}
Fake repository will be like this:
public class MockCongressRepository : ICongressRepository
{
public List<tMember> GetMembers()
{
var members = new List<tMembers>{ new tMember { id = 1 } };
return members;
}
}
Unit test like this:
var controller = new CongressController(new MockCongressRepository());
Unit test using Moq:
var mockCongressRepository = new Mock<ICongressRepository>();
mockCongressReposiory.Setup(mcr => mcr.GetMembers())
.Returns(new List<tMembers>{ new tMember { id = 1 } });
var controller = new CongressController(mockCongressRepository.Object);
Note: Here we got rid of the MockCongressRepository class and the mock is defined close to the unit test.

non primitive data types for modeling?

public class Song
{
public int SongID { get; set; }
public string URL { get; set; }
public virtual TagLib.Tag SongInfo { get; set; }
}
I want to use the "TagLib.Tag" data-type in my Song entity.
When I try to enable migrations I get:
One or more validation errors were detected during model generation:
\tSystem.Data.Entity.Edm.EdmEntityType: : EntityType 'XmpNode' has no key defined. Define the key for this EntityType.
\tSystem.Data.Entity.Edm.EdmEntitySet: : The referenced EntitySet 'Tags' for End 'CombinedImageTag_Exif_Source' could not be found in the containing EntityContainer.
\tSystem.Data.Entity.Edm.EdmEntitySet: : The referenced EntitySet 'Tags' for End 'CombinedImageTag_Exif_Target' could not be found in the containing EntityContainer.
\tSystem.Data.Entity.Edm.EdmEntitySet: : The referenced EntitySet 'Tags' for End 'XmpTag_NodeTree_Source' could not be found in the containing EntityContainer.
\tSystem.Data.Entity.Edm.EdmEntitySet: : The referenced EntitySet 'Tags' for End 'CombinedImageTag_Xmp_Source' could not be found in the containing EntityContainer.
\tSystem.Data.Entity.Edm.EdmEntitySet: : The referenced EntitySet 'Tags' for End 'CombinedImageTag_Xmp_Target' could not be found in the containing EntityContainer.
\tSystem.Data.Entity.Edm.EdmEntitySet: : The referenced EntitySet 'Tags' for End 'CombinedImageTag_OtherTags_Source' could not be found in the containing EntityContainer.
\tSystem.Data.Entity.Edm.EdmEntitySet: : The referenced EntitySet 'Tags' for End 'CombinedImageTag_OtherTags_Target' could not be found in the containing EntityContainer.
\tSystem.Data.Entity.Edm.EdmEntitySet: : The referenced EntitySet 'Tags' for End 'CombinedImageTag_AllTags_Source' could not be found in the containing EntityContainer.
\tSystem.Data.Entity.Edm.EdmEntitySet: : The referenced EntitySet 'Tags' for End 'CombinedImageTag_AllTags_Target' could not be found in the containing EntityContainer.
\tSystem.Data.Entity.Edm.EdmEntitySet: EntityType: EntitySet 'XmpNodes' is based on type 'XmpNode' that has no keys defined.
\tSystem.Data.Entity.Edm.EdmEntitySet: EntityType: EntitySet 'Tags' is based on type 'Tag' that has no keys defined.
How can I use external complex data-types in my model?
I see that the error about Tag entity class that, you didn't define for this Key properties.
Perhaps your code is as follows:
public class Tag
{
public string TagName{get; set;}
// other fields
}
you must change it as follows:
public class Tag
{
[Key]
public int TagId{get; set;}
public string TagName{get; set;}
// other fields
}