Update part of primary key Entity Framework 4.0 - entity-framework-4

I've a table with a compose primary key (3 columns):
UTP_ID (ITEMId)
UTS_ID (CategoryID)
USS_ID (SubCategoryID)
When I try to change SubCategory ,for example,with EF 4 i get follow error:
utl.USS_ID = Convert.ToInt32(ddlSubSetor.SelectedItem.Value);
the property is part of the object's key information and cannot be modified
Any Ideias?Why i can't change it?

EF implements an Identity Map between primary key property values and object references. It doesn't allow to change the key for the same object instance.
I would do this with direct SQL:
objectContext.ExecuteStoreCommand(
"UPDATE MyTable SET USS_ID = {0} WHERE UTP_ID = {1} AND UTS_ID = {2} AND USS_ID = {3}",
Convert.ToInt32(ddlSubSetor.SelectedItem.Value),
utl.UTP_ID, utl.UTS_ID, utl.USS_ID);
Make sure that your entity utl is detached from the context because this code directly writes into the database table and the entity doesn't get any information about this change. But this avoids having to delete and recreate the entity (which might be impossible due to existing foreign key constraints on the old row in the database).

As a result of being part of the entity key the object needs to be deleted from the context and re-attached with the new primary key value.
The Entity Framework works by having a context which manages the state of the entities, a collection of entities (basically the table) and the entity itself (a row of data). As data is read from the database it is added to the entity's collection which in turn is managed by the context for changes of state. Changing an Entity's key is really deleting the entry from the database and inserting a new one. As a result to change an entity key, first delete the entity from it's collection, detach the entity object to allow key modification, change the primary key value and re-attach the entity to the collection. Finally call save changes in the context to apply the changes to the database.
The following code should produce the desired results:
Context.UTLs.DeleteObject(utl);
Context.UTLs.Detach(utl);
Context.SaveChanges();
utl.USS_ID = Convert.ToInt32(ddlSubSetor.SelectedItem.Value);
Context.UTLs.AddObject(utl).
Context.SaveChanges();

Related

Entity Framework DB First Identity Column override?

I have a MVC-Project with a DB-First EDMX file from a production database.
Let's say table Person has an identity-column named ID.
I also have a copy of this database where I have turnd OFF the Identity-Option for the ID column. My goal is to synchronize data between these two databases.
To connect to each of these databases I use the same context-class with different connection-strings.
The problem with this is, that when I try to add a copy of a row from table Person from productionDB to my copyDB I get an error, because EntityFramework is trying to insert NULL for the ID column. I know that this is totally normal, because the EDMX-File has set identity to TRUE for the ID-column of table Person, but is there a way to programatically change this behaviour?
Context prod = new Context("ProductionConnectionString");
Context prodCopy = new Context("CopyConnectionString");
var prodEntity = prod.Person.First(); \\ RETURNS A PERSON WITH ID 1
prodCopy.Person.Add(prodEntity):
prodCopy.SaveChanges(); \\THIS WILL THROW AN EXCEPTION BECAUSE EF WILL REPLACE 1 WITH NULL BECAUSE IDENTITY OPTION
Any ideas?

iOS - Core Data set attribute primary key

I am developing an application in Swift and started using Core Data recently.
I must define which attribute to my entity will be my primary key. For example:
I have an entity that has the attributes of the class:
id
name
age
I need the "id" attribute is my primary key.
May be the same in Objective-C, just need to know how to define it.
Each NSManagedObject has its own unique key built in which is available in its objectID property.
This id is internally used to link entities over its relations. There is no need to maintain an own id as a primary key as you are used to do in SQL.
You can always get the id by NSManagedObject.objectID.
Fetching an object by its id can be performed directly by the managed object context using NSMananagedObjectContext.objectWithId(...)
Why do you need id to be your primary key, it's not SQL and there is not primary key (even if behind core data it's SQL you don't use SQL and primary key). Rename your attribute id in userId, or entityId. When you want to get your entity with your id use a NSPredicate:
[NSPredicate predicateWithFormat:#"(entityId == %d)", entityId]

BreezeJS custom SaveResult containing additional deleted entities

We are parsing the SaveBundle on the server and returning a custom SaveResult. We want to be able to notify the client of additional changed entities as a result of processing the SaveBundle.
For example we have a SaveBundle from the client containing 1 entity to be deleted which when we parse and process on the server we actually delete 2 entities.
As far as we can tell the SaveResult does not contain any properties that would allow us to indicate an entity was 'deleted', rather than say 'modified'.
Is there a way to return additional entity changes through the SaveResult? Or is the only solution to refresh the data by resubmitting a Breeze query client side after the save changes?
I 'think' that if you return the deleted entities with their foreign keys set to null or empty (in the case of non-nullable guids etc.) in the SaveResult then Breeze client-side will detect this and mark them as deleted
I couldn't find anything explicitly in the documentation or the source about this though
here is your answer:
var result = context.SaveChanges(saveBundle);
//create your own EntityInfo object and fill it with the the entity and it's state
var entityInfo = new EntityInfo();
//...
//add it to the result
result.Entities.Add(entityInfo);
//return the result
return result;
Breeze client will then treat that entity like any other entity returned from you normal save proc.
Hope this helps

Setting a collection of related entities in the correct way in EF4 using POCO's (src is the DB)

I have a POCO entity Report with a collection of a related POCO entity Reference. When creating a Report I get an ICollection<int> of ids. I use this collection to query the reference repository to get an ICollection<Reference> like so:
from r in referencesRepository.References
where viewModel.ReferenceIds.Contains(r.Id)
select r
I would like to connect the collection straight to Report like so:
report.References = from r in referencesRepository.References
where viewModel.ReferenceIds.Contains(r.Id)
select r;
This doesn't work because References is an ICollection and the result is an IEnumerable. I can do ToList(), but I think I will then load all of the references into memory. There also is no AddRange() function.
I would like to be able to do this without loading them into memory.
My question is very similar to this one. There, the only solution was to loop through the items and add them one by one. Except in this question the list of references does not come from the database (which seemed to matter). In my case, the collection does come from the database. So I hope that it is somehow possible.
Thanks in advance.
When working with entity framework you must load objects into memory if you want to work with them so basically you can do something like this:
report.References = (from r in referencesRepository.References
where viewModel.ReferenceIds.Contains(r.Id)
select r).ToList();
Other approach is using dummy objects but it can cause other problems. Dummy object is new instance of Reference object which have only Id set to PK of existing object in DB - it will act like that existing object. The problem is that when you add Report object to context you must manually set each instance of Reference in ObjectStateManager to Unchanged state otherwise it will insert it to DB.
report.References = viewModel.ReferenceIds.Select(i => new Reference { Id = i }).ToList();
// later in Report repository
context.Reports.AddObject(report);
foreach (var reference in report.References)
{
context.ObjectStateManager.ChangeObjectState(reference, EntityState.Unchanged);
}

Self referencing foreign key - GUID - Entity framework 4 insert problems

I have successfully used EF4 to insert rows automatically with a server generated GUID:
http://leedumond.com/blog/using-a-guid-as-an-entitykey-in-entity-framework-4/
Now how does one perform this task if there exists a RowID (guid) and ParentRowID (guid) with a primary-foreign key constraint between the two? What would I set .ParentRowID to?
NewCut = New Row With
{
.ParentRowID = .RowID
}
SaveChanges throws a fit every time.
The fact that the primary key is a GUID is in fact irrelevant because I attempted the same test using a standard autogenerated integer without success.
The solution is as simple as the one you have posted.
Just create both parent and child entities in code, do not set Entity Key and not forget to set StoreGeneratedPattern for all server-generated Guid columns.
Then perform either MasterEntityInstance.Children.Add(ChildEntityInstance), or ChildEntityInstance.MasterEntity = MasTerEntityInstance and call SaveChanges.
After the SaveChanges call both guid properties will be populated with the correct Guid values, and ChildEntity.MasterEntity Entity Key will be populated with the necessary MasterEntity Entity Key value.

Resources