Firstly, new to Asp.Net MVC and ADO.NET entity data model.
While practicing an example, I created a table but forgot to set "Identity specification" to true for PK.
Created a model for MVC Application using entity data Model and worked fine.
Later on I've have set that "Identity specification" to true for that table in the DB.
When I try to insert a record an exception is raised and record does not get inserted.
{"Cannot insert explicit value for
identity column in table 'Contacts'
when IDENTITY_INSERT is set to OFF."}
Here is the digner created class in the model, which should have changed as per schema changes in DB
public static Contact CreateContact(int id, string firstName, string lastName, string phone, string email)
{
Contact contact = new Contact();
contact.Id = id;
//
return contact;
}
There is no need for "Id" variable in the above Method Signature as but it is still auto generating that.
How can we make our model to refresh itself or manually,
if the database schema is updated.
NOTE: using C#, ASP.NET MVC
Thanks
Configure your DB schema correctly, then right-click your model and choose "Update Model from Database." This will correct the SSDL in your EDMX, which tells the EF that the id is store generated.
It will not, however, remove the id argument from the CreateContact method. The EF's code generator puts all non-nullable properties in the signature to this method. But once you have updated the SSDL, you should no longer get the exception when you save; if you want to use this method (you don't have to), you can just pass a 0.
Related
What would be the best practice for storing some entity in a SQL Server database, when I have an Id property which is autoincremented (identity)?
This is for a .NET Core application, using Entity Framework Core. I suppose that I could just create some new entity without the identity id, and move the values of my old entity to my new entity the store it in the .Add method of my current context, or execute a command for enable the 'SET IDENTITY_INSERT ON', but both of those approaches looks messy, I'm guessing that there is a cleaner way to achieve this.
//user has autoincremented property
public IEnumerable<User> SaveUser(User user)
{
context.add(user);
context.SaveChanges(); // Exception Cannot insert explicit value for identity column in table
}
I expect to get to do it in a way that I could reuse it in the whole application, because if my entities keep increasing in size, I would have to write this messy code all around.
To start with, I would like to ask/point at your model class. Not sure how you are having your EF on .net core, but if you are to have a model (be it code first or model first),
lets just say, your Entity model looks similar to below:
User
{
UserId (as int),
UserName (as string),
BirthDate (as date)
}
You can achieve the identity insert by below approach:
public class User
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int UserId {get;set;}
public string UserName {get;set;}
public DateTime BirthDate {get;set;}
}
Please explore and learn about Code first approach, Modelling your data, repository patterns (may be the ideal in my perspective but depends on case or could be a good learning) and see to the attributes, annotations decorations for EF models.
To explain on what actually drives the auto identity by the above annotations,
Identity generation (auto identity prop)
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
is the driving factor, also depends on the data type. some data types may need additional param configurations. Explore when you try out on your solution. For example, you can use Guid data type and see how it turns out in your Db.
primary key or key attr
[Key]
is as simple to denote as the primary key field in the model/entity structure. This may not be helping or running the auto identity but, i am explaining about this on why i added this attribute in my sample code above.
I have an entity. This entity's type is activity. I want to set this entity's regardingobjectid field value and then i want to create record. Each record's regardingobjectid field can show different entity. Namely i set this field "a" entity, and then i can set this field with "b" entity on next record. I only have "a" and "b" entities's logicalname. I take object type code with using logicalname. And i take entity metadata with this object type code. How can i take entity id from entity metadata or object typecode with using C#. If i take entity id (a or b) and then i will set it to regardingobjectid which is in activity type entity.
Your wording is pretty confusing. Here is an example which I think covers what you are trying to achieve.
Create a contact, then create a task with the regarding field populated with the contact.
Entity contact = new Entity("contact");
contact["lastname"] = "Test Contact";
Guid contactId = service.Create(contact);
Entity task = new Entity("task");
task["subject"] = "Test Task";
task["regardingobjectid"] = new EntityReference("contact", contactId);
service.Create(task);
You could also update an existing task like so:
Entity task2 = new Entity("task");
task2.Id = new Guid(...);
task2["regardingobjectid"] = new EntityReference("contact", contactId);
service.Create(task);
You can get the record id (for use here new Guid(...) or here contactId) in a variety of ways.
The record id refers to a specific record in CRM, e.g. a row in a table.
If you have created the record using a service call the id is returned to you
immediately.
Entity contact = new Entity("contact");
...
Guid recordId = service.Create(contact);
You can query the record id from CRM. Further reading: IOrganizationService.RetrieveMultiple.
Guid recordId = Service.RetrieveMultiple(new QueryExpression("contact")).Entities.First().Id;
If you have an Entity object returned from CRM you always get its record id from the Id property.
Entity contact = new Entity("contact");
Guid recordId = contact.Id;
Side Notes
Object Type Code (also know as Entity Type Code)
This isn't usually used for anything, it's a piece of data that has a small number of uses - I rarely find it useful or use it.
The type code can be used to refer to a type of entity, e.g. contact, case, etc. However it's preferred to use the entity schema name, e.g. contact, incident, etc.
It's also worth remembering that is isn't reliable - especially in the case of custom entities.
ObjectTypeCode Property
Always use the entity schema name (SchemaName) to refer to a custom
entity in code and queries. Do not use the object type code (also
referred to as entity type) code because its integer value varies for
custom entities in different organizations.
Metadata Services
You can use the metadata services to receive (and manipulate) information regarding the configuration of the system. E.g. which entities you have and what fields those entities have. It will not give you information about specific records however.
Further reading: The metadata and data models in Microsoft Dynamics 365.
An issue occurs when I want to save an object posted back from a form, but exclude a particular field from the resultant SQL statement. In this case I did not want to include the password field in a user edit form.
An edit HttpPost controller method contained this:
db.Users.Attach(user);
db.Entry(user).State = EntityState.Modified;
db.Entry(user).Property(x => x.Password).IsModified = false;
db.SaveChanges();
I assumed that the .IsModified statement would mean that the generated SQL would consist of an UPDATE statement without the password field and so not overwrite the existing password value with null in the database.
However, this was not the case and EF seems to work in a slightly different way. My user class and its associate metadata class did not specify that the password field was required and yet, when executing, there was a ‘Password field required’ DbEntityValidationException thrown when SaveChanges was invoked.
One solution would be to include the password field with its value as a hidden form field, which would suffice in most cases, but in this instance would not be a good idea as password, hashed or otherwise is rather sensitive data.
On further inspection, it seemed that, in this case where we are using a database first approach, the .edmx file contains a ‘not null’ directive on the Password field. When EF comes to execute the actual save, this is checked and the exception raised.
This was not entirely intuitive in my opinion but once it is known it can be worked around.
My solution was to provide a value for the excluded field and retain the .IsModified statement. This means the DbEntityValidationException isn’t thrown as EF sees the Password field containing a value (as prescribed in the .edmx file) but is not actually written to the database due to IsModified being false. E.g.
user.Password = "not required";
db.Users.Attach(user);
db.Entry(user).State = EntityState.Modified;
db.Entry(user).Property(x => x.Password).IsModified = false;
db.SaveChanges();
Is there a better solution to this as using a dummy value as above seems like a bit of a hack?
You haven't really explained why you don't want to save the password field, I'm assuming its just because you don't know what the value is and in your current code it is being set to NULL.
You could use a ViewModel to bind with your webpage, and only supply the fields that are required (so in your case, NOT the password field). When the user POSTs data back, you can load the user from the db, set only the fields you need to, then save the data back. The password field will be unchanged.
For example, assuming the User table is this:
ID
UserName
Password
FullName
You would have a view model class of
public class UserViewModel
{
public int ID { get; set; }
public string UserName { get; set; }
public string FullName { get; set; }
}
When the data is posted back to the server from the client:
using (MyEntity db = new MyEntity())
{
User u = db.Users.Find(userViewModel.ID);
u.UserName = userViewModel.UserName;
u.FullName = userViewModel.FullName;
db.SaveChanges();
}
GO with the stored procedure approach, where you dont need to worry about entity framework, call stored proc from entity framework and update your table inside sql statement without updating password field
I'm trying to develop my first ASP.net MVC project with Entity Framework. I wasn't using any view models, i was using same models for both in views and database transactions. Here is the thing, i have custom user table. In creation, i have 5 things in my User model: UserName, UserPassword, FullName, Branch and BranchId(Navigation to another table). But when i want to edit a user, i don't need the UserPassword field, because changing the password won't be possible for now. So i created a model same with the User model except the UserPassword field named UserEdit.
In create view i use my User model, in edit view i use the UserEdit model. In controller i'm using automapper and copy values from User to UserEdit and return that to view. It's working fine, problem is about updating.
I'm trying to update the user like this:
public bool Update(UserEdit userEdit) {
User user = Find(userEdit.UserUsername);
Mapper.CreateMap<UserEdit, User>();
user = (User)Mapper.Map(userEdit, user, typeof(UserEdit), typeof(User));
if (_modelState.IsValid)
{
_transactionManager.GetContext().Entry(user).State = System.Data.Entity.EntityState.Modified;
_transactionManager.CommitTransaction();
return true;
}
else
{
return false;
}
}
But it gives me this error:
Additional information: The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.
When i check the user i'm trying to update, i see Entity Framework related objects in it. So i'm thinking reason of this error is probably about branch table and those related objects in the user object. I really don't need those entity related objects in my user object. If i could only copy the properties in the model, it would be great. Maybe i'm doing something else wrong. Because i know people use view models all the time, there should be an easy way to do it.
Any ideas?
Thanks
You really shouldn't be rolling your own password authentication. Use what's built into MVC. That said, the easiest way to save your view model would be this;
using (YourContext db = new YourContext())
{
User u = db.User.Find(userEdit.UserUsername);
db.Entity(u).State = System.Data.Entity.EntityState.Modified;
u.FullName = userEdit.FullName;
....set the other properties here...
db.SaveChanges();
}
please, i need help to retrieve ID(primary key) of the object i have inserted in oracle database, many suggestion said:
context.Entity.add(myObject);
context.SaveChanges();
int x=myObject.ID;
but that didn't work.
when i tries to print x in the following statement in controller:
return View(x.ToString());
(Since i can't print this value in another way), i receive the value "0", but when i open the database i found a value for ID (not "0")
my oracle database has sequence and trigger to assign ID to myObject.
i don't know where the problem is, in database? or compatibility problem between database and MVC?
Thank you in advanced:)
The problem is on your model. EF needs to know that the field in question is set in the db.
In your model, add the DatabaseGenerated option like this:
public class myObject
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
...
}
The options that can be used with DatabaseGeneratedOption are Computed (generated on insert and update), Identity (generated on insert), and None (not generated).
Once you do this, EF knows to get the value back from the DB after a save. Otherwise, it assumes the db isn't touching the values you send.