How to map table without primary key Entity Framework - asp.net-mvc

I'm using Entity Framework to map some tables, but I can't do this unless I declare some column as the primary key.
The problem here is that my table in my database don't have a primary key and has millions of rows. I don't have permission to create a new Id column.
[Table("MYTABLE")]
public class myTable
{
[Column("NUMX")]
public virtual string NumX { get; set; }
[Column("NAME")]
public virtual string Name { get; set; }
[Column("AGE")]
public virtual int AGE { get; set; }
}
Obs: If I add the [Key] attribute to some column like Age, it works, but returns the wrong data.
Is there some way to omit the primary key?

I Figured out the problem.
Composite Keys works for me:
eg:
In my Context I defined some keys, not only one, but three keys:
public class MyContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
**//Here is the secret**
modelBuilder.Entity<MyModel>().HasKey(x => new { x.NumX, x.Name,x.Age});
}
}

Entity Framework requires a primary key unlike SQL.
EF use the primary key to uniquely identify rows (for example when you use .Find() or to perform update operations).
Infact not having a primary key remember a SQL VIEW, where you can only read data.
If any of the columns uniquely identify a certain row set it as a primary key (it can't be NULL) also if in Sql it isn't a key.
Otherwise if the combination of the columns are uniquely, create a composite key with these columns.
Remember that you should have a primary key in the 99% of cases, when you don't have a primary key you should stop and think if it make sense.

Related

Set a Primary Key for an Entity without ingaffect database

I'm working on an ASP.NET MVC project, I use Entity Framework (Database First), I created a data model depend on SQL server database, I created a Table in the database and I updated the data model from the database, and when I try to add a record to the new table I created (this table doesn't have a PK) I got an error, when I search about the error I Understood that in Entity Framework need to have a PK for Entity.
So I ASK if I can set a Primary Key for an Entity without affect database, or any other solution to solve this problem.
You can use partial Class for set Key and without effect Original Model and Database
// orginal class **Entity** `YourEntity.cs`
public class YourEntity
{
public int Id { get; set; }
}
Then create a new Class must name different ordinal class ex YourEntityMeta.cs it is physical name
// must change name ordinal class `YourEntity.cs` but add **partial** keyword
[MetadataType(typeof(Metadata))]
public partial class YourEntity
{
sealed class Metadata
{
[Key]
public int Id { get; set; }
}
}
Entity Framework always needs a primary key column with name id. Add a column (id) in the database table and set "Is Identity: true" for it. Then update the database model of your project.

How to rename Primary key Column in code first approach in ASP.net MVC?

I am using EF code first approach. I need to rename my PK column name.
public class classname
{
[Key]
public int OldId { get; set; }
}
I need to change OldId to NewId. I tried renaming my OldId to NewId, I tried updating my database with Migration but that didn't help.
I tried renaming both in column name and model and again when I tried to update my database I still get error.
How can I rename my primary Key column without losing its data?
Is the question that OldId is not used in your code anymore but is still in your database, or is your problem that it OldId is in your code but has a different column name in your database?
You can use fluent API or data annotations if you want to tell entity framework that the name of property in your DbSet has a different column name in the database:
Fluent API Method
public class MyDbContext : DbContext
{
public DbSet<ClassName> ClassNames {get; set;}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// Tell entity framework that you are now building ClassName:
var classNameConfig = modelBuilder.Entity<ClassName>();
// ClassName has an int primary key in OldId:
classNameConfig.HasKey(className => className.OldId);
// "columnX" in the database corresponds with property OldId
classNameConfig.Property(className => className.OldId)
.HasColumnName("columnX");
}
}
Of course in this specific example this can be concatenated into one statement.
The nice thing about fluent API is that you disconnect your classes from the actual database representation. This hides how the actual database names its columns, column order, min size, max size etc from the user of the DbSets.
Just specify a different DbContext, and you can use the same classes with a different Db.
For instance, if you want to use the same entity framework classes in different databases:
class BaseContext : DbContext
{
public DbSet<MyClass> MyClasses {get; set;}
}
// context to be used with database X:
class DataBaseXContext : BaseContext
{
protected override void OnModelCreating(
DbModelBuilder modelBuilder)
{
// I want to use "columnX" for property A, which is optional:
modelBuilder.Entity<MyClass>
.Property(p => p.A)
.HasColumnName("columnX")
.IsOptional();
}
}
// context to be used with database Y:
class DataBaseXContext : BaseContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// I want to use "columnY" for property A, which is required:
modelBuilder.Entity<MyClass>
.Property(p => p.A)
.HasColumnName("columnY")
.IsRequired();
}
}
Data Annotations Method
If you are absolutely sure you want your classes to be used in only one database, with one pre-defined model, you could use Data Annotations.
However, your question shows that it is not uncommon that the same classes will be used in a different database model. So, although this method is very commonly used, I urge you to reconsider a decision to use Data Annotations.
public class classname
{
[Key]
[Column("ColumnX")]
public int OldId { get; set; }
}
changing the Identity column may lead to instability and you cant change anything with the column unless you kill all the Key constraints (all table relation ship)
t will be tooo complicated i would advice you that if data isnt Important then just delete the database and re run migraions it will recreate the database again
The name of the entity property can be different from the name of the database column.
If you need to change the name of the column on the database you can do it with the DBMS manager (SQL Server Enterprise Manager if you are using SQL Server) or running the proper DDL statement (sp_rename on SQL Server) then set the new column name on the property using the attribute ColumnAttribute
[Column("NewId")]
[Key]
public int OldId { get; set; }
If you need to change the name in the code but not on the database you can do a similar thing
[Column("OldId")]
[Key]
public int NewId { get; set; }
In this case you should do a refactor (rename with F2 if you have standard visual studio Keys or Ctrl+R, R if you are using resharper)
If you need to change both you can do both.

What is the purpose of the [Key] attribute on a Primary Key in an asp.net MVC class?

I have read in various places, eg
http://techfunda.com/howto/132/primary-key-and-foreign-key-relationship-in-model
...that if you don't call the Id property in your model "Id" or "id" you need to add the annotation [Key], eg
[Key]
public int MyKey { get; set; }
...to it to tell the compiler it's the primary key in the database.
It seems like this may only be a requirement for Code First sites - although I can't find anything conclusive either way.
What is the purpose of [Key] and when should it be used?
Do I need to decorate any primary keys in models that are not called "Id" even when not building a Code First MVC site?
When you run code first and use this:
public class MyClass{
[Key]
public int MyKey { get; set; }
}
This will create in your database:
Table >> dbo.MyClass
Column >> MyKey IDENTITY NOT NULL
When you create a script to create the table, you need to make sure it is a primary key and it is used for code first approach
public class NewClass{
[key]
public int MyKey {get; set;}
}

ASP.MVC db Find(), but with non-primary key parameter

How does one get a list of results by using a key that is not the primary key? To be more specific, I have a composite primary key where I would like to retrieve all the matches with one column's parameter.
I would think, in an ActionResult in the Controller, it's something like
tableModel tbmodel = db.tableModels.Find(i => i.partialPK == parameter)
but that's not the case, since Find() only works with the entire PK.
I declared my PKs in the entity model class as:
[Key]
[Column(Order = 0)]
public int PK1 { get; set; }
[Key]
[Column(Order = 1)]
public string PK2 { get; set; }
According to DbSet.Find you can pass in the primary keys separated by commas
db.tableModels.Find(PK1, PK2)
The Find method takes an array of objects as an argument. When working with composite primary keys, pass the key values separated by commas and in the same order that they are defined in the model.
However, if you want to just use one value, you will probably have to use
db.tableModels.Where(i => i.partialPK == parameter)
or an equivalent Linq operator
If you're trying to get the object with linq query from database, use: .FirstOrDefault with .Where
Customer customer = db.Customers.Where(c => c.Email == auth.Email).FirstOrDefault();
Here db is DbContext
and Customer is the DbSet

Insert values to entity framework in asp.net mvc4

In my asp.net mvc4 sample i have table in the name of Sample with three column as Name,Dept and Id.In this Id as identity and primary.I get a value for Name and Dept from user and insert that value to Sample table of entity framework.It pass value '0' to Id.And i got an error as "Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries".Please help me.
set "autoincrement" on the column and set the id as primary key in sql server ..
In EF code-first this is done by data annotations. Make sure you recreate your table (or database) after changing the scheme.
public class Sample
{
[Key]
[Required]
[Column(Order = 0)]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)] //auto increment id
public int Id { get; set; }
[Required]
public string Name { get; set; }
[Required]
public int Dept { get; set; }
}
You don't need to pass an integer for Id. EF will resolve this automatically. Just create the object by filling in the name and the dept. By saving the changes to the database, EF will automatically fill in the auto generated Id.

Resources