I am new to MVC and C#. I just stumbled on it and found it interesting. I encountered an issue which will not allow me proceed.
Here is my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MyHotel.Models
{
public class AccountTypes
{
public int AccountTypeID { get; set; }
public string AccountTypeName { get; set; }
}
}
I created the controler and the view thereafter.
And for this, I keep got this error:
One or more validation errors were detected during model generation:
System.Data.Edm.EdmEntityType: : EntityType 'AccountTypes' has no key defined. Define the key for this EntityType.
System.Data.Edm.EdmEntitySet: EntityType: EntitySet "AccountTypes" is based on type "AccountTypes" that has no keys defined.
I google that the answers were to add [Key] over the public int AccountTypeID { get; set; } so it could look like this:
namespace MyHotel.Models
{
public class AccountTypes
{
[Key]
public int AccountTypeID { get; set; }
public string AccountTypeName { get; set; }
}
}
But no result until now.
Note: I am using MVC 4
Description
Entity Framework CodeFirst recognize the key, by default, by name.
Valid names are Id or <YourClassName>Id.
Your property should named Id or AccountTypesId
Another way is to use the ModelBuilder to specify the key.
Sample
public class MyDbContext : DbContext
{
public DbSet<AccountTypes> AccountTypes { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<AccountTypes>.HasKey(x => x.AccountTypeID);
base.OnModelCreating(modelBuilder);
}
}
Mode Information
Entity Framework Code First Tutorial
Try using [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] property to indicate the key field.
The regular field would go with EntityKeyPropert=false.
public class MyDbContext : DbContext
{
public DbSet<AccountTypes> AccountTypes { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<AccountTypes>().HasKey(x => x.AccountTypeID);
base.OnModelCreating(modelBuilder);
}
}
Hi Peter it seens you are missing an "s"
Your Account int should be:
public int AccountsTypeID { get; set; }
Hope it can be solved; Fernando.
Related
I'm working in a Entity Framework + SQLite app, and i don't know how activate PRAGMA foreign_keys = 1 in the Model for C# application.
Here my model (My_model.Context.cs)
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
public partial class My_Model : DbContext
{
public My_Model()
: base("name=My_Model")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<My_TABLE1> My_TABLE1 { get; set; }
public virtual DbSet<My_TABLE2> My_TABLE2 { get; set; }
public virtual DbSet<My_TABLE3> My_TABLE3 { get; set; }
public virtual DbSet<My_TABLE4> My_TABLE4 { get; set; }
}
Any idea?
I have tried modify App.conf doesn't works.
I have found many examples but no works for me.
In your App.Config file, add "foreign keys=true" to the connection string, like this:
data source=c:\wherever\whatever.sqlite;DateTimeFormat=InvariantCulture;foreign keys=true
This is my model:
public class RepoDocument
{
public DocumentRecord Document { get; set; }
public string Title { get; set; }
public string Path { get; set; }
}
This is the sub class definition:
public class DocumentRecord
{
public Guid Id { get; set; }
public string Name { get; set; }
// ... Other fields here...
}
What I need
I want to have Id as my primary key for the RepoDocument model.
I am using this code in my db context:
public class DocumentsContext : DbContext
{
public DocumentsContext()
: base("name=DbConnectionString")
{
}
public DbSet<RepoDocument> DocumentsTable { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<RepoDocument>().HasKey<Guid>(c => c.Document.Id);
}
}
The problem
However, I am getting the following error when I run add-migration in the Package Manager Console:
The properties expression 'c => c.Document.Id' is not valid. The expression should represent a property: C#: 't => t.MyProperty' VB.Net: 'Function(t) t.MyProperty'. When specifying multiple properties use an anonymous type: C#: 't => new { t.MyProperty1, t.MyProperty2 }' VB.Net: 'Function(t) New With { t.MyProperty1, t.MyProperty2 }'.
Question
How can I set the property of a sub-class of my model as the primary key of the database using fluent API?
Your question is incorrect. You should be using inheritance.
public abstract class RepoDocument
{
public Guid Id { get; set; }
public string Title { get; set; }
public string Path { get; set; }
}
public class Document : RepoDocument
{
public string Name { get; set; }
// ... Other fields here...
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<RepoDocument>().ToTable("RepoDocument");
modelBuilder.Entity<Document>().ToTable("DocumentRecord");
}
I suppose, you cannot, if your sub-class (btw, I've read sub-class as descendant first time) is used as entity - it will be stored in separate table, but your RepoDocument will have no key in that case.
I'm not sure, if it's possible, if you will register DocumentRecord as ComplexType, but you could try. it will be stored in the same table in that case, so sounds possible.
You could create separate type for configuration, then add it inside OnModelCreating.
public class DocumentRecordConfiguration: ComplexTypeConfiguration<DocumentRecord>
{
public DocumentRecordConfiguration()
{
/* use fluent api here */
}
}
I would like to create an Association Property with the following setup:
public class ClassType1{
[Key]
public int type1_ID { get;set; }
public int type2_ID { get;set; } // In database, this is a foreign key linked to ClassType2.type2_ID
public ClassType2 type2Prop { get;set; }
}
public class ClassType2{
[Key]
public int type2_ID { get;set; }
}
My problem is that type2Prop can't find it's foregin key. It is trying to look for "type2Prop_ID", which does not exist, when it should really be looking for "type2_ID". Here is the error I get:
{"Invalid column name 'type2Prop_ID'."}
How do I tell it which property to use as ClassType2's key?
Try a ForeignKeyAttribute on type2Prop:
using System.ComponentModel.DataAnnotations.Schema;
public class ClassType1
{
[Key]
public int type1_ID { get; set; }
public int type2_ID { get; set; } // In database, this is a foreign key linked to ClassType2.type2_ID
[ForeignKey("type2_ID")]
public virtual ClassType2 type2Prop { get; set; }
}
public class ClassType2
{
[Key]
public int type2_ID { get;set; }
}
You can also do it using the Fluent API in a refactor-proof way (i.e. if you change the name of your property in the future, the compiler will let you know you have to change the mapping as well). It's a bit uglier for simple cases like this, but it's also more robust. In your DbContext class, you could add something like:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<ClassType1>().HasRequired(x => x.type2Prop)
.WithMany()
.HasForeignKey(x => x.type2_ID);
}
public class ClassType1{
[Key]
public int type1_ID { get;set; }
[ForeignKey("type2Prop")]
public int type2_ID { get;set; } // In database, this is a foreign key linked to ClassType2.type2_ID
public ClassType2 type2Prop { get;set; }
}
public class ClassType2{
[Key]
public int type2_ID { get;set; }
}
I have an error:
One or more validation errors were detected during model generation:
\tSystem.Data.Entity.Edm.EdmEntityType: : EntityType 'DynamicMenu' has no key defined. Define the key for this EntityType.
\tSystem.Data.Entity.Edm.EdmEntitySet: EntityType: EntitySet 'ambt_Dynamic_Menu' is based on type 'DynamicMenu' that has no keys defined.
in helper class which code is:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Data.Models;
using Data;
namespace Ambermoda.Web
{
public class MenuHelper
{
public static List<DynamicMenu> GetMenu()
{
DataContext db = new DataContext();
List<DynamicMenu> list = db.ambt_Dynamic_Menu.ToList();
return list;
}
}
}
so I have no idea how can I solve it. I checked everything what (in my opinion) can generate this error, but with any results.
I sam similar posts but any of them doesn't solve my problem.
If anybody have some idea, pleas write it :)
Thanks!
Some more code
DynamicMenu.cs
[Table("abmt_Dynamic_Menu")]
public class DynamicMenu
{
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int dmn_id { get; set; }
public string dmn_code { get; set; }
public string dnm_parent_code { get; set; }
public string dnm_title { get; set; }
public string dnm_title_en { get; set; }
public int dnm_order { get; set; }
}
DataContext.cs
public class DataContext : DbContext
{
public DataContext() { }
public DbSet<DynamicMenu> ambt_Dynamic_Menu { get; set; }
}
Connection string:
<add name="DataContext" providerName="System.Data.SqlClient" connectionString="Data Source=Mikasasa-lap\Mikasasa;Database=Ambermoda;Integrated Security=True;Pooling=False;"/>
According to source code you provided, you're working with the Code First approach.
CF assumes that class should have property named "Id" by the naming convention, and this property will be treated as primary key.
Otherwise, you should manually declare primary key via attribute [Key] or using fluent API (see EntityTypeConfiguration.HasKey method).
You need to inform what field is your database Primary Key. Use the attribute Key to do this:
[Table("abmt_Dynamic_Menu")]
public class DynamicMenu
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int dmn_id { get; set; }
public string dmn_code { get; set; }
public string dnm_parent_code { get; set; }
public string dnm_title { get; set; }
public string dnm_title_en { get; set; }
public int dnm_order { get; set; }
}
Check whether the DyanmicMenu table has primary key
I am using the Microsoft Entity Framework with code first to manage my data (with MySQL). I have defined a POCO object, however, when I try to add data it says table Users doesn't exist. I looked in the DB and it created table User not Users. How can I remedy this? It is driving me nuts!
Thanks!
public class User
{
[Key,Required]
public int UserId { get; set; }
[StringLength(20), Required]
public string UserName { get; set; }
[StringLength(30), Required]
public string Password { get; set; }
[StringLength(100), Required]
public string EmailAddress { get; set; }
[Required]
public DateTime CreateDate { get; set; }
[Required]
public bool IsActive { get; set; }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
namespace YourNamespace
{
public class DataContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder dbModelBuilder)
{
dbModelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
public DbSet<User> User { get; set; }
}
}
I have not used MySQL with EF yet but regardless I think the solution is unbias. You need to turn off Pluralize Table Convention.
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions.Edm.Db;
public class MyDbContext: DbContext
{
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
Now EF will look for the literal of your object name to the table name.
Some great video tutorials are at http://msdn.microsoft.com/en-us/data/aa937723 under the Continue Learning Entity Framework. For additional learning experience, you can not specify the above but rather explicitly map the object 'user' to the table 'user'.
Additional References:
http://blogs.msdn.com/b/adonet/archive/2010/12/14/ef-feature-ctp5-fluent-api-samples.aspx
You can put an attribute on the class telling the name of the table:
[Table("Users")]
public class User
{
//...
}
...or you could use the fluent API. To do this you will override the OnModelCreating method in your DbContext class.
public class MyDbContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().Map(t => t.ToTable("Users"));
}
}
In future versions of EF, we've been promised the ability to write our own conventions. Thats not in there yet as of version 4.1...
(Haven't tried it with MySQL...)