I have this error
Invalid object name 'dbo.Vacancies'
But I have Model for Vacancies.
Here it is:
public partial class Vacancy
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Vacancy()
{
this.Interwiers = new HashSet<Interwier>();
this.InvitationMails = new HashSet<InvitationMail>();
}
[Key]
public int Vacancy_Id { get; set; }
[Display(Name="Вакансия")]
public string VacancyName { get; set; }
public Nullable<int> CompanyID { get; set; }
public virtual Company Company { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Interwier> Interwiers { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<InvitationMail> InvitationMails { get; set; }
}
}
Also I have table Vacancy.
This code I have in IdentityModels:
public System.Data.Entity.DbSet<SmartSolutions.Models.Vacancy> Vacancies { get; set; }
Here is code of View where I try to show data from table.
// GET: VacanciesAll
public ActionResult Index()
{
var vacancies = db.Vacancies.Include(v => v.Company);
return View(vacancies.ToList());
}
Here is the Table:
Here is the table in EF
Why am I getting an error?
Check if the Table exists in your Sql Database. Chances are it is not there in your Database, hence, the error.
If the table exists, make sure you are mapping your EF table to the correct table name in DbContext.
It could be loooking at the wrong database.
The DbContext class should match the name in the connection string.
Make sure your connection string "name" property is correct.
Example: PortalEntities DbContext should match PortalEntities in connectionStrings.
public class PortalEntities : DbContext
{
public DbSet<Delegate> Delegates { get; set; }
public DbSet<Status> Statuses { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Database.SetInitializer<PortalEntities>(null);
base.OnModelCreating(modelBuilder);
}
}
<connectionStrings>
<add name="PortalEntities" connectionString="Data Source=serverName;Integrated Security=true;Initial Catalog=dbName;" providerName="System.Data.SqlClient"/>
</connectionStrings>
Please check the EF Layers [ SSDL - CSDL - MSL ]
this is conflict between your EF layers and database engine
Related
I am trying to build database on MySQL server in .Net Framework 4.5.2 using Entity Framework 6.2.0. For connection with MySql I use nugets MySQL.Data, MySQL.EntityFramework, MySQL.Web all at version 8.0.16. Connection works fine.
The problem is with code first approach and generating behaviour on foreign key constraints. I want to have On Delete Set Null behaviour but simply cannot get it in generated database. All I have for now is On Delete Restrict or Cascade. Is this a problem with MySQL, Connector, EF6?
I tried to set relation with this behaviour with fluent api. I have read that setting property with fk constraint nullable should do the trick. I also have disabled On Delete Cascade by addding .WillCascadeOnDelete(false).
Here are two entities that I want to connect with simple One to Many relation:
public class Company
{
public long Id { get; set; }
public string Name { get; set; }
public long? AddressId { get; set; }
public virtual Address Address { get; set; }
}
public class Address
{
public long Id { get; set; }
public string Street { get; set; }
public string Number { get; set; }
public string ZipCode { get; set; }
public string City { get; set; }
public virtual ICollection<Company> Company { get; set; }
}
And the DbContext:
[DbConfigurationType(typeof(MySqlEFConfiguration))]
class OwrContext : DbContext
{
public OwrContext() : base(nameof(OwrContext))
{
DbConfiguration.SetConfiguration(new MySqlEFConfiguration());
}
public virtual DbSet<Address> Address { get; set; }
public virtual DbSet<Company> Company { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Entity<Company>()
.HasOptional(c => c.Address)
.WithMany(a => a.Company)
.HasForeignKey(c=>c.AddressId)
.WillCascadeOnDelete(false);
}
}
I feal that there is a problem with MySQL connector, but maybe there is something else I could try?
I have my application configured to use a SQLRoleManager. I simply created the database, configured the web.config, and let the application create and populate the database tables.
I would like an admin view to preform some simple operations such as add and remove users. Thus, I have created an entity framework data context using the scaffolding wizard and directed it to build around the tables only. (did not check views and stored procedures).
The next thing i wished to do was to then scaffold the controller and view and eventual the model for this data. When I right click controllers I select the add controller with views using entity framework. I fill out the appropriate information selecting an empty class for the model.
I receive the following error which indicates the data is missing keys yet they are in fact defined on the database and in the entity model. Any thoughts as to where i am going wrong here? Do I need to pre build the model? I was hoping to have visual studio create these automatically.
EDIT
Again, the tables all have primary and foreign keys. I can confirm this from Sql Management Studio as well as the .edmx diagram. The bellow code was auto generated. Do i need to add keys?
Context.edmx
UserRole_Context.tt > aspnet_Users.cs
//------------------------------------------------------------------------------
// <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 IDM.DAL
{
using System;
using System.Collections.Generic;
public partial class aspnet_Users
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public aspnet_Users()
{
this.aspnet_PersonalizationPerUser = new HashSet<aspnet_PersonalizationPerUser>();
this.aspnet_Roles = new HashSet<aspnet_Roles>();
}
public System.Guid ApplicationId { get; set; }
public System.Guid UserId { get; set; }
public string UserName { get; set; }
public string LoweredUserName { get; set; }
public string MobileAlias { get; set; }
public bool IsAnonymous { get; set; }
public System.DateTime LastActivityDate { get; set; }
public virtual aspnet_Applications aspnet_Applications { get; set; }
public virtual aspnet_Membership aspnet_Membership { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<aspnet_PersonalizationPerUser> aspnet_PersonalizationPerUser { get; set; }
public virtual aspnet_Profile aspnet_Profile { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<aspnet_Roles> aspnet_Roles { get; set; }
}
}
UserRole_Context.Context.cs
//------------------------------------------------------------------------------
// <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 IDM.DAL
{
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
public partial class IDMEntities : DbContext
{
public IDMEntities()
: base("name=IDMEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<aspnet_Applications> aspnet_Applications { get; set; }
public virtual DbSet<aspnet_Membership> aspnet_Membership { get; set; }
public virtual DbSet<aspnet_Paths> aspnet_Paths { get; set; }
public virtual DbSet<aspnet_PersonalizationAllUsers> aspnet_PersonalizationAllUsers { get; set; }
public virtual DbSet<aspnet_PersonalizationPerUser> aspnet_PersonalizationPerUser { get; set; }
public virtual DbSet<aspnet_Profile> aspnet_Profile { get; set; }
public virtual DbSet<aspnet_Roles> aspnet_Roles { get; set; }
public virtual DbSet<aspnet_SchemaVersions> aspnet_SchemaVersions { get; set; }
public virtual DbSet<aspnet_Users> aspnet_Users { get; set; }
public virtual DbSet<aspnet_WebEvent_Events> aspnet_WebEvent_Events { get; set; }
}
}
Connection String
<add name="IDMEntities" connectionString="metadata=res://*/DAL.UserRole_Context.csdl|res://*/DAL.UserRole_Context.ssdl|res://*/DAL.UserRole_Context.msl;provider=System.Data.SqlClient;provider connection string="data source=*******;initial catalog=IDM;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" /></connectionStrings>
I've made a simple Entity Framework ASP Core Application that works but I do not know why:
I've made a context like this:
public class AstootContext : DbContext
{
public AstootContext(DbContextOptions<AstootContext> options)
: base(options)
{ }
public DbSet<Account> Accounts { get; set; }
public DbSet<User> Users { get; set; }
}
And I have two tables with models like this:
public class Account
{
public int Id { get; set; }
public string Username { get; set; }
public string PasswordHash { get; set; }
public DateTime Created { get; set; }
List<User> Users { get; set; }
}
public class User
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public DateTime Birthday { get; set; }
public Account Account { get; set; }
}
The interesting thing is that when I run my application it actually can pick up the data. It just seems weird because I have not specified any table mapping.
I'm assuming this just automaps because the specified tables are the same name.
My questions are:
How do I specify Table explicit table mapping in case I do not want my model names to be exactly the same as the DB?
How do I specify Custom Column Mapping.
Is there anything special I have to specify for Primary/Foreign Keys
edit
To clarify
Say I had a table in the DB MyAccounts and I wanted to map that to an entity Accounts.
Say I had a column password and I wanted that to map to a POCO property PasswordHash
To specify the name of the database table, you can use an attribute or the fluent API:
Using Attributes:
[Table("MyAccountsTable")]
public class Account
{
public string PasswordHash { get; set; }
}
Using Fluent API:
public class YourContext : DbContext
{
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<Language>(entity => {
entity.ToTable("MyAccountsTable");
});
}
}
To name your columns manually, it's very similar and you can use an attribute or the fluent API:
Using Attributes:
public class Account
{
[Column("MyPasswordHashColumn")]
public string PasswordHash { get; set; }
}
Using Fluent API:
public class YourContext : DbContext
{
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<Language>(x => x
.ToTable("MyAccountsTable")
.Property(entity => entity.PasswordHash)
.HasColumnName("MyPasswordHashColumn")
);
}
}
After reading this good BLOG about adding custom data to UserProfile table, I wanted to change it the way that UserProfile table should store default data + another class where all additional info is stored.
After creating new project using Interenet application template, I have created two classes:
Student.cs
[Table("Student")]
public class Student
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public virtual int StudentId { get; set; }
public virtual string Name { get; set; }
public virtual string Surname { get; set; }
public virtual int UserId { get; set; }
}
UserProfile.cs
[Table("UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
public virtual int StudentId { get; set; }
public virtual Student Student { get; set; }
}
also, I've deleted the UserProfile definition from AccountModel.cs. My DB context class looks like this:
MvcLoginDb.cs
public class MvcLoginDb : DbContext
{
public MvcLoginDb()
: base("DefaultConnection")
{
}
public DbSet<UserProfile> UserProfiles { get; set; }
public DbSet<Student> Students { get; set; }
}
again, I have deleted db context definition from AccountModel.cs.
Inside Package-Manager-Console I've written:
Enable-Migrations
and my Configuration.cs looks like this:
internal sealed class Configuration : DbMigrationsConfiguration<MvcLogin.Models.MvcLoginDb>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
}
protected override void Seed(MvcLogin.Models.MvcLoginDb context)
{
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
if (!WebSecurity.UserExists("banana"))
WebSecurity.CreateUserAndAccount(
"banana",
"password",
new
{
Student = new Student { Name = "Asdf", Surname = "Ggjk" }
});
}
}
That was the idea of adding student data as creating a new class, but this approach is not working because after running Update-Database -Verbose I'm getting the error:
No mapping exists from object type MvcLogin.Models.Student to a known managed provider native type.
Can anyone expain why I'm getting this error, shoud I use a different approach for storing additional data in different table?
I struggled a lot with the same issue. The key is to get the relation between the UserProfile class and your Student class correct. It have to be a one-to-one relationship in order to work correct.
Here is my solution:
Person.cs
public class Person
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
/* and more fields here */
public virtual UserProfile UserProfile { get; set; }
}
UserProfile.cs
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
public virtual Person Person { get; set; }
}
MyDbContext.cs
public class MyDbContext : DbContext
{
public DbSet<Person> Person { get; set; }
public DbSet<UserProfile> UserProfile { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<UserProfile>()
.HasRequired(u => u.Person)
.WithOptional(p => p.UserProfile)
.Map(m => m.MapKey("PersonId"));
}
}
However, I also struggled with creating users with the WebSecurity.CreateUserAndAccount method. So I ended up creating my Person objects with Entity Framework and then create the user account with the membership provider method:
AccountRepository.cs
public Person CreatePerson(string name, string username) {
Person person = new Person { Name = name };
_dbContext.Person.add(person);
_dbContext.SaveChanges();
var membership = (SimpleMembershipProvider)Membership.Provider;
membership.CreateUserAndAccount(
model.UserName,
createRandomPassword(),
new Dictionary<string, object>{ {"PersonId" , person.Id}}
);
}
HenningJ, I'm searching for an answer to the same thing. Unfortunately (I'm sure you're aware) the problem with the way you did this is that there is no SQL transaction. Either your SaveChanges() or CreateUserAndAccount() could fail leaving your user database in an invalid state. You need to rollback if one fails.
I'm still searching for the final answer, but I'll post whatever solution I end up going with. Hoping to avoid having to write a custom membership provider (AGAIN!), but starting to think it would be faster.
I've got a class defined
public class ReportClass
{
public int ID { get; set; }
public int ClassIndex { get; set; }
public string ClassName { get; set; }
public int CompanyID { get; set; }
}
and I set up a dbcontext.
public class ReportClassContext : DbContext
{
public DbSet<ReportClass> ReportClasses { get; set; }
}
When I first went to get records, the runtime tells me the database table doesn't exist: I check, and I see that the name of my DbSet doesn't match with the table. I switched the name to match:
public class ReportClassContext : DbContext
{
public DbSet<ReportClass> ReportClassesRealTable { get; set; }
}
but it is still querying against the non-existent table.
What am I doing wrong?
Use the table attribute like this:
[Table("ReportClassesRealTable")]
public class ReportClass
{
public int ID { get; set; }
public int ClassIndex { get; set; }
public string ClassName { get; set; }
public int CompanyID { get; set; }
}
This tells the EF what the actual table name is for your class, otherwise it attempts to use the plural form of your class name.
Let this be there as it is
public DbSet<ReportClass> ReportClasses { get; set; }
Now overrde the OnMoedlCreateing method to tell EF to map this class to a different table using fluent API. Add that method to your DBContext class
public class ReportClassContext : DbContext
{
public DbSet<ReportClass> ReportClasses { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<ReportClass>().ToTable("ReportClassesRealTable");
}
}
This tells EF that when you query ReportClasses property of your DbContxt object, It will fetch data from teh ReportClassRealTable table in your database.