I currently have a page that displays a list of settings. The table of data has 3 fields called Name(PK), BrandCode and Value. The data comes from a database which doesn't contain an ID field and within my application I want to be able to edit this data within all the fields if necessary. I am able to edit the BrandCode and Value but not the Name as it is set as the primary key. Is there a way around this so that I am also able to edit the Name field?
Model
[Table("Settings")]
public class ServiceSettings
{
[Key]
public string Name { get; set; }
public string BrandCode { get; set; }
public string Value { get; set; }
}
This is the error that I receive when i click Save Changes.
Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded
If you require any more information then please let me know.
Thanks in advance.
If you have access to your database - create an Id column which you use as your key and set your Name column to Unique.
Updating a PK column is awful practice - don't do it.
I want to answer the question though.If there is no other solution, a workaround (I'd call it hack) would be:
1) Save all your data from your row temporarily
2) Delete the row
3) Create a new row with all the updated values
If you have foreign keys, you'll also need to update them.
I would not recommend this solution though. Only use it if absolutely necessary. It is not without reason that PKs should not be updated.
I am sharing just one of the suggestion or better approach :)
Please do not try to make name as PK because it might contains same data.
You can also create temporary ID column and declare it as PK
If it is existing big database, where editing table is possible, So you can make Name as Unique key and create another ID PK.
Hope this post will solve your issue :)
You can't edit the primary key field.
Your only solution that doesn't involve adding a specific ID field to the database is to create an id field in your model:
[Table("Settings")]
public class ServiceSettings
{
[Key]
public int Id { get; set; } // Created ID field
public string Name { get; set; }
public string BrandCode { get; set; }
public string Value { get; set; }
}
and populate it when you load your data.
It may be better to use a GUID rather than an int to ensure uniqueness.
Related
I am making a web app, and one of the db tables holds client information and design settings for the site:
public class Client
{
public string Name { get; set; }
public string SiteName { get; set; }
public string PrivacyStatement { get; set; }
public bool HasLogo { get; set; }
// some more properties
}
This table will never have more than one record, and it does not have any related tables. Is it ok to omit the PK in this case?
Will the record will always be static ?
If Yes, it is absolutely fine to omit the Primary key if you are 100% sure that this table will have only one record and also do not have any relation with other tables.(Why do you even want to store it in table? Think a bit)
If NO, then also you don't need to store it in a table simply store it in a object and change it accordingly.
There is also a nice discussion on this post about primary key you can look into it.
Should each and every table have a primary key?
I have an EF question for you: I have these two classes
public class Post
{
public long Id {get;set}
public string Content {get;set;}
public virtual ICollection<Comment> Comments {get;set;}
}
public class Comment
{
public long Id {get;set;}
public string Content {get;set;}
}
I created a database at first with these columns and EF created foreign key with Id column of Post class, but then I added UniqKey column as my new primary key:
public class Post
{
public long Id {get;set}
public string Content {get;set;}
public string UniqKey {get;set;} //New Field will be my new primary key
public virtual ICollection<Comment> Comments {get;set;}
}
and I want to change my foreign key to use UniqKey instead of Id.
I want to update database without deleting and losing any data.
Any help appreciated
Thanks
You should operate on database first (maybe with management studio if you are using SQLserver or with Toad preferred in this case).
First of all make a back-up of the database.
Then add the column UniqKey with allowed null.
Now update the table and add manually the value of UniqKey.
Remove the constraints and key relative to Id.
Remove allowed null to Uniqkey and add the constraint and the key to it.
In your model add the attribute [Key] and [DatabaseGenerated(DatabaseGeneratedOption.None)]
Don't forget you have to change also foreign key of Comments
Give a look here link1 and here link2 also.
If your database has only these two table you can also think to use database first approach, and use the new context created by wizard instead of old one you created with code-first approach
I have a problem with populating the right values in a junction table for a many to many relationship. In the image below I have simplified what I am trying to do. The "Table on the left" has values in the database that I want to use. The table of the right is about to receive new records. It has a navigation property to the Junction table and the same is true for the table on the left. The junction table has navigation properties to both tables on its rear and they are set to required.
When I create the new records in the table on the right, I also add to it records in the junction table. The TOL_ID is known as it is saved in the database, but the TOR_ID is about to be created, therefore unknown. When I attempt to call the SaveChanges in my context, it tries to save the junction table records first, before the TOR_IDs have been populated for the record on the right. I though that marking the navigation property as Required would make the EF understand that TOR_ID must exist before creating the junction table row. Instead it tries to insert an existing TOL_ID and 0, which gives a violation when trying to insert many table on the right records connected to the same TOL_ID.
Note: Saving the TOR_IDs first and then connecting with junction records is not an option, as the creation of the junction table records are part of a "Slowly changing dimension" type 6 flow.
This is how it really looks like in the code:
// The newRating is the new object corresponding the Table on the right
var newRating = new ModuleRating()
{
// The moduleRating.RatedDriveUnit already exists in the db
RatedDriveUnit = moduleRating.RatedDriveUnit
};
newModule.Ratings.Add(newRating);
If you follow the Code First below classes will helpful
public class TOL
{
[Key]
public int TOL_ID { get; set; }
public int Col1 { get; set; }
public ICollection<TOR> Tors { get; set; }
}
public class TOR
{
[Key]
public int TOR_ID { get; set; }
public int Col1 { get; set; }
public ICollection<TOL> Tols { get; set; }
}
public class TolTorContext : DbContext
{
public DbSet<TOL> Tols { get; set; }
public DbSet<TOR> Tors { get; set; }
}
If you follow database first approach,make FK at Join Table and try to chhange id names TOLId , TORId
I'am sorry for spending your time. After some investigation I noticed that the supposed composite unique index (TOL_ID and TOR_ID) of the junction table had been set wrong. Instead two separate unique indexes had been applied to TOL_ID and TOR_ID, which resulted a constrain violation as soon as one of those two values appeared twice.
i'm working on C# MVC 4 web app
i created a page linked to a DB and my question is that in the Create New record the user can enter the ID, Name, ...
how can i hide in the View from the user the ID and make it take an auto incremental number for example when the user goes to page Create New he will have to start filling the Name, Address ... without seeing the ID field which must take automatically the value of a number:
here is my model code:
public partial class Employee
{
public int Identifier { get; private set; }
public string Name { get; set; }
public string Address { get; set; }
public string Status { get; set; }
}
You should let the DB handle the Id incrementation. I would set the Id to private in case you need it for business operations. But you can remove it from the view.
Edit the view and remove the ID part from it, then it depends by how you designed the DB, if you have auto-increment in it, otherwise you should manage it in the controller.
Matteo
Use a AutoIncrement database field.
Here are some common ways to do that
If after your INSERT INTO statement you want to get the ID your database generated put
SELECT SCOPE_IDENTITY();
for SQL Server to return the ID it generated.
Usually you use a Guid to represent an ID. The reason for this is that you can not know the last ID of the last inserted entity (in your case Employee). To find it you you insert it into the database (let the db handle the increment) and the database server responds with the incremented ID.
To know the exact ID of the inserted entity use a Guid. The Guid is a very large integer that has a very small chance of being idendical to another inserted Guid. Thus you wont have to wait for the database to respond with the inserted ID.
Note you can not bast the Guid to an int. You have to change the field type.
When trying to use this code:
var model = new MasterEntities();
var customer = new Customers();
customer.Sessionid = 25641;
model.Customers.Add(customer);
model.SaveChanges();
I get:
{"Cannot insert the value NULL into column 'Sessionid', table
'master.dbo.Column'; column does not allow nulls. INSERT
fails.\r\nThe statement has been terminated."}
The column "Sessionid" is actually the primary key and is marked with [KEY] like this:
public class Customers
{
[Key]
public long Sessionid { get; set; }
public long? Pers { get; set; }
}
So according to this question, it seems as if when the property is marked with [KEY], EF ignores my own declaration of Sessionid since it expects the database to assign the value.
So how can I solve this? If I remove [KEY] I get the "entity type has no key defined" exception...
I solved it by adding [DatabaseGenerated(DatabaseGeneratedOption.None)] like this:
public class Customers
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public long Sessionid { get; set; }
public long? Pers { get; set; }
}
You can configure SQL to auto-generate (and auto-increment) the primary key for the table upon inserts. Then just remove the [Key] in C# and you don't need to set the ID in the application manually, the db will generate it for you.
I have encountered this problem multiple times while working with Microsoft SQL Server and I have followed the same way to fix it. To solve this problem, make sure Identity Specification is set to Yes. Here's how it looks like:
In this way the column number auto increments as a primary key normally would.
HOW?: right-click the table that contains the column, choose Design, select the primary key and in Column Properties window find Identity Specification and set it to Yes.