If I have a SharedDocument
entity with two properties I want to be related to my ApplicationUser
entity, how do I do this?
On this MS Tutorial , see if you name the property the same as the PK of the table you want to relate EF can find the relationship pretty easily. But I have two properties, CreatedBy
& ModifiedBy
that I want related to my User
table but I do not want to name them AspNetUserId
. How can I do this?
Model
public class SharedDocumentModel : DbContext
{
public SharedDocumentModel()
: base("MyContext")
{
}
public virtual DbSet<SharedDocument> PortalDocuments { get; set; }
}
public class SharedDocument
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime Created { get; set; }
public virtual ApplicationUser CreatedBy { get; set; }
public DateTime Modified { get; set; }
public virtual ApplicationUser ModifiedBy { get; set; }
public string ContentType { get; set; }
public string FileType { get; set; }
public byte[] FileContent { get; set; }
public double Version { get; set; }
}
}
Error on creating View with Model SharedDocuments
There was an error running the selected code generator:
'Unable to retrieve metadata for
'MVC.WebSite.Models.SharedDocument'. One or more validation
errors 'mere detected during model generation:
MVC.WebSite.DAL.IdentityUserLogin: EntityType 'IdentityUserLogin'
has no key defined. Define the key for this EntityType.
MVC.WebSite.DAL.IdentityUserRoIe: EntityType 'IdentityUserRoIe' has
no key defined. Define the key for this EntityType.
IdentityUserLogins: EntityType: EntitySet 'IdentityUserLogins' is based
on Vpe 'IdentityUserLogin' that has no keys defined.
IdentityUserRoles: EntityType: EntitySet 'IdentityUserRoles' is based on
type 'IdentityUserRole' that has no keys defined.
You can do that by adding ForeignKey :
[ForeignKey("CreatedById")]
[ForeignKey("ModifiedById")]
So in you case:
public class SharedDocument
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime Created { get; set; }
[ForeignKey("CreatedById")]
public virtual ApplicationUser CreatedBy { get; set; }
public string CreatedById { get; set; }
public DateTime Modified { get; set; }
[ForeignKey("ModifiedById")]
public virtual ApplicationUser ModifiedBy { get; set; }
public string ModifiedById { get; set; }
public string ContentType { get; set; }
public string FileType { get; set; }
public byte[] FileContent { get; set; }
public double Version { get; set; }
}
One more thing: Merge your DbContext
with ApplicationDbContext
and use one database:
public class ApplicationUser : IdentityUser
{
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
return userIdentity;
}
}
public class SharedDocumentModel : IdentityDbContext<ApplicationUser>
{
public SharedDocumentModel()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public virtual DbSet<SharedDocument> PortalDocuments { get; set; }
public static SharedDocumentModel Create()
{
return new SharedDocumentModel();
}
}
Your error message may be related to referencing ApplicationUser because it is in the IdentityDbContext<ApplicationUser>
context. You can either setup your app context to inherit from the IdentityDbContext<ApplicationUser>
, otherwise you will need to setup a copy of DbSet<ApplicationUser>
in your SharedDocumentModel context.
You must match name of FK with property name not property type. So if you have a property with type User
and name CreatedBy
your FK property must CreatedByID
not UserID
. Therefore you could simply Add following 2 properties to your SharedDocument
class.
public class SharedDocument
{
public string CreatedByID { get; set; }
public virtual ApplicationUser CreatedBy { get; set; }
public string ModifiedByID { get; set; }
public virtual ApplicationUser ModifiedBy { get; set; }
// rest of your code
}
As you can see the type of FK properties are string
since type of ApplicationUser
's PK is string
also.
But another important issue, it seems you are using Identity's default configuration. If so you already have a DbContext
on your project named ApplicationDbContext
. Find it and add your other Entities to it. Don't implement new DbContext
.
// This class already added to your project
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
// This context already had ApplicationUser set you don't need to add it again
// add your own new entities
public DbSet<SharedDocument> PortalDocuments { get; set; }
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
At the end keep in mind to configuring EF you have 3 option:
1) Configuration by conventions, as I have done above.
2) Configuration by Data Annotation. By Adding Attribute to Properties or clasees:
[ForeignKey("CreatedById")]
public virtual ApplicationUser CreatedBy { get; set; }
3) Or by fluent API:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<SharedDocument>()
.HasRequired(e => e.CreatedBy)
.WithMany()
.Map(e => e.MapKey("CreatedByID"));
modelBuilder.Entity<SharedDocument>()
.HasRequired(e => e.ModifiedBy)
.WithMany()
.Map(e => e.MapKey("ModifiedByID"));
}
// rest of code same as before
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.