unable to add view when using model - c#

I have the following model in my application, but when I try to generate a view on the controller using it I get the error "Unable to retrieve metadata for Jop_Offers_Website.Models.JobRequest":
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using WebApplication3.Models;
namespace Jop_Offers_Website.Models
{
public class JobRequest
{
public int Id { get; set; }
public string Message { get; set; }
public DateTime ApplyDate { get; set; }
public int JobId { get; set; }
public string UserId { get; set; }
public virtual Jobs job { get; set; }
public virtual ApplicationUser user { get; set; }
}
}
When I use other models to add view, or if I comment out the job and user properties the view is generated successfully.
The Jobs Model:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
namespace Jop_Offers_Website.Models
{
public class Jobs
{
//id to be primary key of Jobs table
public int Id { get; set; }
//job title
[Required]
[Display (Name ="أسم الوظيفة")]
public string JobTitle { get; set; }
//job description
[Required]
[Display(Name ="وصف الوظيفة ")]
public string JobDescription { get; set; }
//jop image
[Display(Name ="صورة الوظيفة ")]
public string JobImage { get; set; }
//id of categories to relate to Job category Type 1 to many relationship
//[Required]
public int CategoryId { get; set; }
//object of category to detect job category
public virtual categories category { get; set; }
}
}
The ApplicationUser model:
using System.Data.Entity;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
namespace WebApplication3.Models
{
// You can add profile data for the user by adding more properties to your ApplicationUser class, please visit https://go.microsoft.com/fwlink/?LinkID=317594 to learn more.
public class ApplicationUser : IdentityUser
{
public string UserType { get; set; }
public string Neabouring { get; set; }
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 ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("JobConnection", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
public System.Data.Entity.DbSet<Jop_Offers_Website.Models.categories> categories { get; set; }
public System.Data.Entity.DbSet<Jop_Offers_Website.Models.Jobs> Jobs { get; set; }
public System.Data.Entity.DbSet<Jop_Offers_Website.Models.RoleViewModel> RoleViewModels { get; set; }
public System.Data.Entity.DbSet<Jop_Offers_Website.Models.JobRequest> JobRequests { get; set; }
}
}
Any model used to add views but I can't add the view by using JobRequest Model
and when I use JobRequest model without ApplicationDbContext the view is generated successfully .

Related

asp.net Controller: how can I save data for a "history" table simultaneously with deleting a table with similar information?

I'm attempting to create a history page/table for my website, where when the User completes a workout the Current User Workout table deletes the Workout information upon completion (which is already functioning), AND a history table is updated with the identical fields + a DateTime so that the user can see previous workouts they have completed.
Currently, I am confused on how to implement this. My current "complete" function in the Controller looks like this:
[HttpPost, ActionName("Complete")]
[ValidateAntiForgeryToken]
public ActionResult CompleteConfirmed(int id)
{
UserCurrWorkout userCurrWorkout = db.UserCurrWorkouts.Find(id);
db.UserCurrWorkouts.Remove(userCurrWorkout);
db.SaveChanges();
return RedirectToAction("Index");
}
which is just CRUD code for deleting information in a table based on ID. What I wish to add to this is, very simply, something like:
var oldWorkouts = new UserWorkoutHistory { UserId = model.UserId, UserOldWorkout = model.UserActiveWorkout };
db.UserWorkoutHistories.Add(oldWorkouts);
just above the db.UserCurrWorkouts.Remove code. The “model” of my current workout database isn’t recognized in the function, however, how to make it so is my primary question unless there is a better approach.
Any information or tips would be greatly appreciated! Let me know if you would like to see any other code that may bring clarity to my issue!
EDIT: Here is UserCurrWorkout Model:
namespace Powerlevel.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Spatial;
[Table("UserCurrWorkout")]
public partial class UserCurrWorkout
{
[Key]
public int UCWId { get; set; }
public int UserId { get; set; }
public int UserActiveWorkout { get; set; }
public virtual User User { get; set; }
public virtual WorkoutExercise WorkoutExercise { get; set; }
}
}
and UserWorkoutHistory model:
namespace Powerlevel.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Spatial;
[Table("UserWorkoutHistory")]
public partial class UserWorkoutHistory
{
[Key]
public int UWHId { get; set; }
private DateTime Date = DateTime.Now;
public DateTime CurrentTime
{
get { return Date; }
set { Date = value; }
}
public int UserId { get; set; }
public int UserOldWorkout { get; set; }
public virtual User User { get; set; }
public virtual WorkoutExercise WorkoutExercise { get; set; }
}
}
If I'm getting your point right, I think this is what you need:
[HttpPost, ActionName("Complete")]
[ValidateAntiForgeryToken]
public ActionResult CompleteConfirmed(int id)
{
UserCurrWorkout userCurrWorkout = db.UserCurrWorkouts.Find(id);
var oldWorkouts = new UserWorkoutHistory { UserId = userCurrWorkout.UserId, UserOldWorkout = userCurrWorkout.UserActiveWorkout };
db.UserWorkoutHistories.Add(oldWorkouts);
db.UserCurrWorkouts.Remove(userCurrWorkout);
db.SaveChanges();
return RedirectToAction("Index");
}
Update:
Also the foreign key WorkoutExercise_LinkId of oldWorkouts must in assigned in this line too:
var oldWorkouts = new UserWorkoutHistory { UserId = userCurrWorkout.UserId, UserOldWorkout = userCurrWorkout.UserActiveWorkout , WorkoutExerciseId = 'a valid key from WorkoutExercise table'};
Update 2:
Although, first you need to define a foreign key in the UserCurrWorkout entity and avoid EF to generate an fk column in the database that does not exist in the entity:
[Table("UserCurrWorkout")]
public partial class UserCurrWorkout
{
[Key]
public int UCWId { get; set; }
public int UserId { get; set; }
public int UserActiveWorkout { get; set; }
public virtual User User { get; set; }
public int WorkoutExerciseId { get; set; } // The explicit foreign key
public virtual WorkoutExercise WorkoutExercise { get; set; }
}

MVC 5 Code First adding new database table with UserId

So right now my IdentityModels.cs looks like this:
using System;
using System.Data.Entity;
using System.Security.Claims;
using System.Security.Policy;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using System.Collections.Generic;
using System.Web.Mvc;
using System.Linq;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Leepio.Models
{
// You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more.
public class ApplicationUser : IdentityUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string City { get; set; }
//company
[Display(Name = "Virkshomedsnavn")]
public string CompanyName { get; set; }
public string ZipCode { get; set; }
//company
public int NrEmployees { get; set; }
//company
public string WorkField { get; set; }
public string Language { get; set; }
//Student
public string University { get; set; }
public string StudyProgramme { get; set; }
public int Semester { get; set; }
public string GraduationDate { get; set; }
//
[AllowHtml]
public string Description { get; set; }
//Student
public string Skills { get; set; }
public string Website { get; set; }
public string Address { get; set; }
//Student
[DataType("date")]
public DateTime DateOfBirth { get; set; }
public virtual ICollection<Blog> Blogs { get; set; }
public virtual ICollection<Application> Applications { get; set; }
public virtual ICollection<Project> Project { get; set; }
public virtual IList<Experience> Experience { get; set; }
public virtual ICollection<Skill> Skill { get; set; }
public virtual IList<Education> Education { get; set; }
public virtual IEnumerable<Experience> ExperienceOrdered { get { return Experience.OrderByDescending(e => e.EndYear); } }
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 ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
public System.Data.Entity.DbSet<Leepio.Models.Project> Projects { get; set; }
public System.Data.Entity.DbSet<Leepio.Models.NewsletterMails> NewsletterMails { get; set; }
public System.Data.Entity.DbSet<Skill> Skill { get; set; }
public System.Data.Entity.DbSet<Leepio.Models.Application> Applications { get; set; }
public System.Data.Entity.DbSet<Leepio.Models.Contract> Contracts { get; set; }
public System.Data.Entity.DbSet<Leepio.Models.Experience> Experience { get; set; }
public System.Data.Entity.DbSet<Leepio.Models.Blog> Blogs { get; set; }
public DbSet<Category> Categories { get; set; }
public DbSet<Education> Educations { get; set; }
}
}
What I want to do is, through code (migrations), add a new table as an extensions to the user table (AspNetUsers) through code as to when I register a new user with data taken from facebook, the data that I don't need for the main Users Table can go to the second one, lets say call it "FBData" with the appropriate userId.
To put it in perspective:
Register user would add userID, FirstName, LastName, Email to Users table and at the same time add ID and Locale, Gender in the FBData table.
Microsoft Identity uses AspNetUserClaims to store all additional data you specified in your ApplicationUser model class. When you use external Authentication Provider such as Facebook, Google etc. a new entry is created in AspNetUserLogins table to store the ProviderKey. This key is used when user is logging in to your application for the second time.
For my understanding your plan to create a FBData table is not necessarily good. How about you add Google Authentication after? Will you create a GData table?
The best option would be in your AccountController in ExternalLoginCallback (function triggered when the user is redirected back from your external authentication provider to your page) map what you received from facebook to your ApplicationUser and maybe redirect the the user to the registration form with pre-populated fields to finish the registration cycle. All the trash data you can store if you like in a separate table AspNetUserClaims_External but you have to model it first.
Check:
https://github.com/IdentityServer/IdentityServer4.Samples/tree/dev/Quickstarts/4_ImplicitFlowAuthenticationWithExternal
There are a few things you need to do. First you can create a FbData class with the properties you need in that table. Then add the properties you need to the ApplicationUser Class. You need the foreign key for the FbData table
public int FbDataId { get; set; }
and you also need to add the virtual property for the table:
public virtual ICollection<FbData> FbDatas { get; set; }
Last in your IdentityContext add you DbSet for your table:
public DbSet<FbData> FbData { get; set; }
Run the application on a clean db to see your changes reflected..
You can also override the OnModelCreating class in your IdentityContext to make any modifications to the Generated Identity Tables.

EntityType has no key defined error despite defining key

I'm following the tutorial listed here:
http://dotnetawesome.blogspot.com/2014/07/nested-webgrid-with-expand-collapse-in-aspnet-mvc4.html using my VS2015 Enterprise IDE.
However when at step 8 I go to right click the List() ActionResult in OrderController and select Add View with the following:
I get the following error:
However in the tutorial they don't use a key for OrderVM. Even when I do add [Key] and the proper using and after rebuilding I still get the same error and I'm at a complete loss as to why given I'm using getters and setters.
ViewModels:
OrderVM
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using WebAppTest.Models;
namespace WebAppTest.ViewModels
{
public class OrderVM
{
[Key]
public OrderMaster order { get; set; }
public List<OrderDetail> orderDetails { get; set; }
}
}
Models (Generated from doing a CodeFirst from DB):
MyModel
namespace WebAppTest.Models
{
using System;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
public partial class MyModel : DbContext
{
public MyModel()
: base("name=MyDatabaseEntities")
{
}
public virtual DbSet<OrderDetail> OrderDetails { get; set; }
public virtual DbSet<OrderMaster> OrderMasters { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<OrderDetail>()
.Property(e => e.Product)
.IsUnicode(false);
modelBuilder.Entity<OrderDetail>()
.Property(e => e.Rate)
.HasPrecision(10, 2);
modelBuilder.Entity<OrderDetail>()
.Property(e => e.Amount)
.HasPrecision(10, 2);
modelBuilder.Entity<OrderMaster>()
.Property(e => e.OrderAmount)
.HasPrecision(10, 2);
modelBuilder.Entity<OrderMaster>()
.Property(e => e.CustomerName)
.IsUnicode(false);
modelBuilder.Entity<OrderMaster>()
.Property(e => e.CustomerAddress)
.IsUnicode(false);
}
}
}
OrderDetail
namespace WebAppTest.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Spatial;
public partial class OrderDetail
{
[Key]
public int OrderDetailsID { get; set; }
public int OrderID { get; set; }
[Required]
[StringLength(100)]
public string Product { get; set; }
public int Quantity { get; set; }
[Column(TypeName = "numeric")]
public decimal Rate { get; set; }
[Column(TypeName = "numeric")]
public decimal Amount { get; set; }
}
}
OrderMaster
namespace WebAppTest.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Spatial;
[Table("OrderMaster")]
public partial class OrderMaster
{
[Key]
public int OrderID { get; set; }
public DateTime OrderDate { get; set; }
[Column(TypeName = "numeric")]
public decimal OrderAmount { get; set; }
[Required]
[StringLength(100)]
public string CustomerName { get; set; }
[StringLength(200)]
public string CustomerAddress { get; set; }
}
}
Controllers
OrderController
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using WebAppTest.Models;
using WebAppTest.ViewModels;
namespace WebAppTest.Controllers
{
public class OrderController : Controller
{
// GET: Order
//public ActionResult Index()
//{
// return View();
//}
public ActionResult List()
{
List<OrderVM> allOrder = new List<OrderVM>();
// here MyDatabaseEntities is our data context
using (MyModel dc = new MyModel())
{
var o = dc.OrderMasters.OrderByDescending(a => a.OrderID);
foreach (var i in o)
{
var od = dc.OrderDetails.Where(a => a.OrderID.Equals(i.OrderID)).ToList();
allOrder.Add(new OrderVM { order = i, orderDetails = od });
}
}
return View(allOrder);
}
}
}
Here is the logic of Scaffolder to check for key field:
First finds all properties with this criteria:
Property should be primitive type or if not primitive, one of these: string, decimal, Guid, DateTime, DateTimeOffset, TimeSpan.
Then Tries to find key based on name:
[Id] Property (case insensitive)
[ClassName][Id] Property (case insensitive)
Tries to find key based on attributes:
Property having Key Attribute
Property having EdmScalarProperty Attribute with value of EntityKeyPropety=true
Property having Column Attribute with value of IsPrimaryKey=true
So you should have a filed in your class that meets one of above criterias.
Also you should remove [Key] from your order property because complex types can not be key.
As an option you can add this property to your class:
[Key]
public int OrderID { get; set; }
And as another option your OrderVM class can be like this:
public partial class OrderVM
{
public OrderVM()
{
orderDetails = new List<OrderDetails>();
}
[Key]
public int OrderID { get; set; }
public DateTime OrderDate { get; set; }
public decimal OrderAmount { get; set; }
[Required]
[StringLength(100)]
public string CustomerName { get; set; }
[StringLength(200)]
public string CustomerAddress { get; set; }
public List<OrderDetail> orderDetails { get; set; }
}
I just encountered this problem. I tried adding [Key], I used public string Id { get; set; }. Ultimately the fix was that I just needed to rebuild my project. I wanted to leave this answer here just in case someone in the future was having this issue.
I had encountered the problem. I found out I had another class with the same class name in another namespace. Just rename that class then the issue is solved.

Trying to add a controller, unable to retrieve metadata, no primary key define, even though it looks like there is

All the help I found so far said to define the primary key with [Key] and it must be named ID or YourClassNameID. As far as I can see i have this is the correct format but I'm still getting this error:
![Unable to retrieve metadata for 'DARTPRO.Models.Members'. One or more validation errors were detected during model generation:
DARTPRO.Models.PlayerScores: :EntityType 'PlayerScores' has no key defined. Define the key for this EntityType.
Players_Scores: EntityType: EntitySet 'Players_Scores' is based on tpye 'PlayerScores' that has no keys defined.]1
When creating a controller like this:
![Model class: (DARTPRO.Models)
Data context class: DartConnection(DARTPRO.Models)]2
Here's the code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
namespace DARTPRO.Models
{
public class DartConnection : DbContext
{
public DbSet<Members> Member_Details { get; set;}
public DbSet<PlayerScores> Players_Scores { get; set;}
}
[Table("MenmbersProfile")]
public class Members
{
[Key]
public int MembersID { get; set; }
public string Forename { get; set; }
public string Surname { get; set; }
public string Nickname { get; set; }
public string Contactnumber { get; set; }
public string Address { get; set; }
}
[Table("PlayersGameDetials")]
public class PlayerScores
{
[Key]
public int PlayerScoresID { get; set; }
public int HigestScore { get; set; }
public double ThreeDartAverage { get; set; }
public double OneDartAverage { get; set; }
public int DartsThrown { get; set; }
public int MembersID { get; set; }
}
}
You have some typos in your code
[Table("MenmbersProfile")]
should that be MembersProfile? Menmbers
[Table("PlayersGameDetials")]
Another typo? Details not Detials.
I suggest manually create your database tables matching your code first classes and make sure you have no typos, and set Primary Keys on the tables in the database to match the [Key] attribute in your classes.
I also have the following override in my model, to control the pluralisation of table names.
Also if you want to control the target of the DbConext you can add your own contructor
public class DartConnection : DbContext
{
public DartConnection()
{
// override the connection string
this.Database.Connection.ConnectionString = ConfigurationManager.ConnectionStrings["MyAppSettingDB"].ConnectionString;
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}

The current Model no longer mathces the modes used to pre-generate the mapping views

I am trying to access a table in a database using EF 6.1.0 But I am getting an error when I try get the data from one particular table in the database. I imported the database from an already existing database with a ado.net item.
Here is the code where I get an error:
var dbSrc = new WebInterfaceOldEntities();
List<ut_User> users = dbSrc.ut_User.ToList(); <===== error
Here is the error im getting:
The current model no longer matches the model used to pre-generate the mapping views, as indicated by the ViewsForBaseEntitySets879d00ec20bbbe0601fa7418ff0a96685f5823797e74e2cf3e6f22fdb0b43cc9.MappingHashValue property. Pre-generated mapping views must be either regenerated using the current model or removed if mapping views generated at runtime should be used instead. See http://go.microsoft.com/fwlink/?LinkId=318050 for more information on Entity Framework mapping views.
And here is my Ut_User 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>
//------------------------------------------------------------------------------
namespace FillkDb
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
public partial class ut_User
{
public int UserID { get; set; }
public string Name { get; set; }
public string Password { get; set; }
public string Email { get; set; }
public Nullable<int> AccessLevel { get; set; }
public Nullable<int> Creator { get; set; }
public string Company { get; set; }
public string PhoneWork { get; set; }
public string PhoneHome { get; set; }
public string Cell { get; set; }
public string AddressStreet1 { get; set; }
public string AddressStreet2 { get; set; }
public string AddressStreet3 { get; set; }
public string AddressPostCode { get; set; }
public System.Guid msrepl_tran_version { get; set; }
}
}
And here is the context:
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
public partial class WebInterfaceOldEntities : DbContext
{
public WebInterfaceOldEntities()
: base("name=WebInterfaceOldEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<ut_User> ut_User { get; set; }
...
}

Categories

Resources