I'm getting error while using TryUpdateModel for updating the model with the posted value.
Error is:
The property 'ID' is part of the object's key information and cannot be modified.
I have set ID as primary key in the database table. Any help would be appreciated.
/// <summary>
/// Edit hotel for the event
/// </summary>
/// <param name="id">Eventinstance ID</param>
/// <param name="form">Form parameters</param>
/// <returns>return the new added hotel model to view</returns>
[HttpPost]
public ActionResult EditHotelForEvent(int id, FormCollection form)
{
EventHotelDetail hoteldetails = eventRepo.getHotelbyID(id);
if (ModelState.IsValid && TryUpdateModel(hoteldetails)) // update the model with the form values
{
hoteldetails.isDefault = true;
EventRepository.ApplyModifiedProperties(hoteldetails);
ViewData["success"] = "Hotel added successfully";
eventRepo.Save();
}
return View("AddHotelForEvent", hoteldetails);
}
You cannot modify the primary key (ID in your case).
Why would you like to change the id? id is a unique number that should have no meaning but being unique to a specific object, and therefore should not be modified. if you want another object create another one, but don't trying modifying the id.
Edit:
Check these instructions, primary key might be missing from your database:
Step 1: Check whether your table is having primary key column in database or not. If it does not have any primary key than add a primary key. Because if we don't add a primary key to table than entity framework creates its own key collection and add all columns in it.
Step 2: Open your .edmx file to see table object mapping. You will be able to see each column of table is having icon like primary key. So Write click on your page and update .edmx from database.
Step 3: If you still see same primary key icons on all columns than click on column name you want to update one by one and go to property window and Set Entity Key property to false.
Taken from here.
The error message clearly states the problem. You're trying to modify the primary key of the entity and it's not allowed.
Related
Please tell me details process and files in which changes need to make for showing the foreign key value in place of id as shown in the snap below:
Data Gridview generated using Ajax Crud Generator
My Scenario is I have two table 1) Screen and 2) SubScreen Table, The
Table Screen has two fileds screenId and screenName
And Table SubScreen has subscreenId subscreenName and Screen_ScreenId (as a foreign key) in the view of SubScreen Table I want to show screenName (from Screen table) in place of Screen_ScreenId (of SubScreen Table View)
Finally I found a solution to show foreign key value in place of foreign key id: I am posting this solution so that others who face the same issue can use this method to implement this in their code..
In the model class a relation function need to be created in my case:
my model class is Subscreen.php this has a relation function
public function getScreenScreen()
{
return $this->hasOne(Screen::className(), ['screenId' => 'Screen_ScreenId']);
}
the above mentioned function was auto generated when generated the model using the gii module.
What extra i did here in the model is added one more function code is as shown below
public function getScreenName()
{
return $this->screenScreen->screenName;
}
-------------------------Model changes ends up here-----------------------------
Now come to the _columns.php file of the view which was auto generated while generating the CRUD code using the Ajax Crud Generator extension..
...
[
'class'=>'\kartik\grid\DataColumn',
'attribute'=>'Screen_ScreenId',
'value'=>function($model){return $model->getScreenName();},
],
...
the last line in above code 'value'=>function($model) {return $model->getScreenName();}, is added by me as a extra line to get the functionality up in the view...this made it possible for me to show the ScreenName in place of their Id in the view.
Hope this will help you to solve the same issue...
I have a block of code that is not working as I thought it would.
I have set an Entity up as follows and have a previous guid.
parentEnt = new Entity("vehicle_ent");
parentEnt.id = guid;
Now when I do a check with a statement:
if (parentEnt.Contains("attribute_field")) {
parentEnt["attribute_field"] = "test";
}
The above will never be called because the if statement fails.
However, if I remove the if statement. I am able to actually assign and run the code:
parentEnt["attribute_field"] = "test";
Is there something I am missing with the Contains Method? I thought it was used to check if the Entity contains the attribute?
On the Entity class, you can always assign an attribute like the example you provided whether or not it exists. If it exists, it will overwrite it (which is what you discovered).
So
parentEnt["attribute_field"] = "test";
Will always work, whether or not the attribute already has a value assigned.
When you run the constructor for a CRM entity object, and assign it a guid
Like
Entity parentEnt = new Entity("vehicle_ent");
parentEnt.id = guid;
you are creating a new object of the entity type with the 'vehicle_ent' logical name and a id of 'guid' At this point all the attribute/properties that belong to an entity with that name, are not created along with the entity object, and you only have an Entity class object with a LogicalName and id set.
If you want to check if an entity record with that id contains a certain attribute, you need to fetch is from the database, using your the organization service, like
ColumnSet attributes = new ColumnSet(true);
parentEnt = _service.Retrieve("vehicle_ent", guid, attributes);
After the retrieve is called you can check if the entity record contains the attribute you need to check.
I just add a couple of things:
The syntax entity[attributename] and entity.Attributes[attributename] are equivalent, the reason can be found inside the Entity metadata:
public object this[string attributeName] { get; set; }
the method maps at entity level the Attributes property (the type of this property is AttributeCollection an inherit from DataCollection<string,object> and the base type is an IEnumerable<KeyValuePair<TKey, TValue>>)
DataCollection contains this method:
// Summary:
// Gets or sets the value associated with the specified key.
//
// Parameters:
// key:
// Type: TKey. The key of the value to get or set.
//
// Returns:
// Type: TValue The value associated with the specified key.
public virtual TValue this[TKey key] { get; set; }
this method adds the key (our attributename) inside the collection if the key is not present before. For this you can assign a value to an attribute without using the Contains method first. Of course when you read the value you need to check if the key is present, this is the purpose of the Contains method, but to read the values the GetAttributeValue can be used as well (but it's necessary to pay attention to the default values returned when the attribute is not inside the collection)
I have the following Edit method:
[HttpPost]
public ActionResult Edit(Movie movie)
{
try
{
_db.ApplyCurrentValues("Movies1",movie);
_db.SaveChanges();
return RedirectToAction("Index");
}
catch
{
return View();
}
}
I get the error below when I run it:
An object with a key that matches the key of the supplied object could not be found in the ObjectStateManager. Verify that the key values of the supplied object match the key values of the object to which changes must be applied.
A couple points:
I did not get the error the first time I did an update, only subsequent updates.
Movies1 is the the name of the EntitySet when I view the edmx designer. Is this what it shold be or should it be the name of the table (Movie)?
I have seen things regarding Attach, but I am confused as to what exactly that is.
Inorder to apply current values an entity with that given key should be present in ObjectStateManager. The documentation for the ApplyCurrentValues states
Copies the scalar values from the supplied object into the object in
the ObjectContext that has the same key.
You can attach the entity and apply current values.
_db.Movies.Attach(movie);
_db.ObjectStateManager.ChangeState(movie, EntityState.Modified);
_db.SaveChanges();
I've been trying to insert row in the table having an identity column RequestID (which is primary key as well)
HelpdeskLog logEntry = new HelpdeskLog { RequestBody = message.Body };
if (attachment != null)
logEntry.Attachments = Helper.StreamToByteArray(attachment.ContentStream);
Database.HelpdeskLogs.InsertOnSubmit(logEntry);
But my code inevitably throws following error
Can't perform Create, Update or Delete operations on Table because it has no primary key.
despite primary key column exists indeed
That's what I tried to do:
To look in debugger the value of identity column being inserted in object model. It is 0
To insert manually (with SQL) fake values into table - works fine, identity values generated as expected
To assure if SQLMetal has generated table map correctly . All OK, primary key attribute is generated properly
Nevertheless, neither of approaches helped. What's the trick, does anybody know?
I've also had this problem come up in my C# code, and realized I'd forgotten the IsPrimaryKey designation:
[Table (Name = "MySessionEntries" )]
public class SessionEntry
{
[Column(IsPrimaryKey=true)] // <---- like this
public Guid SessionId { get; set; }
[Column]
public Guid UserId { get; set; }
[Column]
public DateTime Created { get; set; }
[Column]
public DateTime LastAccess { get; set; }
}
this is needed even if your database table (MySessionEntries, in this case) already has a primary key defined, since Linq doesn't automagically find that fact out unless you've used the linq2sql tools to pull your database definitions into visual studio.
LINQ does not allow to insert data into table without primary key. To achieve the insert data with table without primary key you can either use store procedure or create a query and execute using LINQ. Below link provide good explanation of the same.
Can't perform Create, Update or Delete operations on Table(Employee) because it has no primary key
Delete the table and then reinsert it. You must make sure there is a little small key next to the field before you do this. Recompile your project and all should be fine.
Just because you updated the dabase does not mean the DBML file somehow automatically updated. It does not, sorry.
As the the table has the primary key in SQL Server, re-addthe table in the linq2sql designer.
If that were not the case, you can configure which properties are part of the primary key by hand on the designer.
I have generated linq to sql entites but cannot figure out how to assign null to a nullable column. whenever i try to assign null to it it says "there is no implicit type conversion between int and ". BTW the type of the field is int? and the database column is also nullable.
Try to assign it System.DBNull instead
It seems as though the column isn't really nullable. Check the properties of the column and see that it really is marked as nullable. If it isn't, check your database model and try to recreate the LINQ to SQL model if it's nullable in the database.
Mind that you can't simply mark it as nullable in the LINQ to SQL model and not in the database, since these kinds of discrepancies may cause your LINQ to SQL model to stop working.
Post edit update: I can see that the field type is int? which is the same as Nullable<int> so there shouldn't be a problem to set it to null. However, when getting the integer value, you should use the Value property of the int?. Is that the problem?
Usually I've had to use DBNULL.Value when assigning or comparing a database value to null.
You only need to assign then entites nullable property to null. I've never had to assign or test against System.DBNull when using linq-to-sql entities.
It sounds like the generated entity classes have been manually modified or are out of date from the database.
For your reference, the following is a nullable and a non-nullable integer field:
private int? _someID;
/// <summary>
/// Gets or sets the SomeID.
/// </summary>
[Column(Name="SomeID", Storage="_someID", DbType="INT", UpdateCheck=UpdateCheck.Never)]
public int? SomeID
{
private int _someOtherID;
/// <summary>
/// Gets or sets the SomeOtherID.
/// </summary>
[Column(Name="SomeOtherID", Storage="_someOtherID", DbType="INT NOT NULL", CanBeNull=false, UpdateCheck=UpdateCheck.Never)]
public int SomeOtherID
{
Check your generated entity looks something like the above.
You wrote 'the type of the field is int?'.
I guess this is the problem: the type of the field should be int (without the ?), and the property 'allow null value' should be set to true.
In the designer you can change the field type to int? instead of int and 'allow null', but you run into all kind of trouble this way (as you might have noticed).
It is when you're trying to explicitly create a DB set with a nullable column in an entity.
new Nullable() is what you're looking for.
someEntity newEntity = new someEntity()
{
aNullableInt = new Nullable<Int32>()
};