HI
I have a project with uses EF self tracking objects.I am trying to add a relationship to an object . (parentobject.relationshipObject.Add(New relationshipObject...)).
But it throws an error:
Cannot change ObservableCollection
during a CollectionChanged or
PropertyChanged event.
This error occurs in the #Region "Association Fixup" of the code created by the template.
Initially the mainobject does not bring any relationship. Only when the item is selected by the user the relationships are updated in the item.
i found that if i remove the MainObject from the collection and readd it with the relationships this error does not occur. if i only update the relationship object in the mainObject , this issue occurs when i add a new relationship object from the client side
any help is much appreciated
--code sequence is as follows
1. get all the parent entities.
2. when user select an entity get the relationship of the entity and update the relationship entity
parentCol.AsEnumerable.Where(Function(x) x.ID = e.Result.ID).FirstOrDefault().StopTracking()
parentCol.AsEnumerable.Where(Function(x) x.ID = e.Result.ID).FirstOrDefault().relationshipEntity = e.Result.relationshipEntity
parentCol.AsEnumerable.Where(Function(x) x.ID = e.Result.ID).FirstOrDefault().StartTracking()
to add a new item in the relationEntity
Dim newRel As New relationshipEntity
newRel.Ref_parent_Id = parentItem.ID
newRel.REF_rel_ID = relItem.Id
parentItem.relationshipEntity.Add(newRel) ---> Throws error here
the relationshipEntity denotes the relationship table between the parent entity and another entity (many to many relationship).
thanks
Are you trying to add a new child while setting the child's parent?
Since EF tries to fix up one way links on two way relationships, I assume this could cause such an issue.
E.g.
parent.Add(new Child { Parent = parent, Name = "abc" });
As opposed to letting EF do the other side of the connection
parent.Add(new Child { Name = "abc" });
or
new Child { Parent = parent, Name = "abc" });
Related
I'm quite new in Vaadin and have faced next issue. I'm trying to represent my list of entities using Tree with grouping by some properties. Everything was fine till the first level of items. What I've done:
MyEntity myEntity1 = new MyEntity(1l, "prop1", "sub_prop0")
MyEntity myEntity2 = new MyEntity(2l, "prop1", "sub_prop1")
MyEntity myEntity3 = new MyEntity(3l, "prop2", "sub_prop2")
BeanContainer<Long, MyEntity > entityContainer = new BeanContainer<>(MyEntity .class);
marketContainer.setBeanIdProperty("prop"); // prop is property name for the second value in constructor
entityContainer.addBean(myEntity1);
entityContainer.addBean(myEntity2);
entityContainer.addBean(myEntity3)
Tree markets = new Tree("Markets");
markets.setContainerDataSource(entityContainer);
as a result I've got the Tree with 2 items: prop1 and prop2 but nothing else. Actually the only I need additional is to have sup-elements with values form another property as a child items.
Thanks in advance.
Have a look at the documentation and example found here.
In short:
Set the parent of the child object
// Set it to be a child.
tree.setParent(l2, l1);
If no children are allowed, tell it so
/* Make the moons look like leaves. */
tree.setChildrenAllowed(l2, false);
If you wish to define the Hierachie in the Container, then use one of the Containers implementing the HierarchicalContainer.
There you also use the setParent(...) method to specify relationships.
I have this code in a Windows Service targeted to .Net 4.5 that uses a database-first Entity Framework layer:
var existingState = DataProcessor.GetProcessState(workerId);
existingState.ProcessStatusTypeId = (int)status;
existingState.PercentProgress = percentProgress;
existingState.ProgressLog = log;
DataProcessor.UpdateProcessState(existingState);
And this code in a data processing class in the same solution:
public ProcessState GetProcessState(int id)
{
using (var context = new TaskManagerEntities())
{
var processes = (from p in context.ProcessStates.Include("ProcessType").Include("ProcessStatusType")
where p.IsActive && p.ProcessStateId == id
select p);
return processes.FirstOrDefault();
}
}
public ProcessState UpdateProcessState(ProcessState processState)
{
using (var context = new TaskManagerEntities())
{
context.ProcessStates.Add(processState);
context.Entry(processState).State = System.Data.EntityState.Modified;
context.SaveChanges();
}
return processState;
}
ProcessState is a parent to two other classes, ProcessStatusType and ProcessType. When I run that code in the windows service, it retrieves a record, updates the entity and saves it. Despite the fact that the ProcessType child is never used in the above code, when the save on the ProcessState entity is performed, EF does an insert on the ProcessType table and creates a new record in it. It then changes the FK in the ProcessStatus entity to point it at the new child and saves it to the database.
It does not do this in the ProcessStatusType table, which is set up with an essentially identical FK parent-child relationship.
I now have a database full of identical ProcessType entries that I don't need, and I don't know why this is occurring. I feel like I'm making some obvious mistake that I can't see because this is my first EF project. Is the issue that I'm allowing the context to expire in between calls but maintaining the same entity?
Using Add will set the state of all elements to Added, which is causing the child elements to be inserted. The parent element is not inserted as you specify EntityState.Modified for this element.
Try using the following in the UpdateProcessState rather than using Add.
context.ProcessStates.Attach(processState);
context.Entry(processState).State = EntityState.Modified;
context.SaveChanges();
Attach will set the state of all elements to Unchanged and by specifying Modified for the parent element you are indicating that only this element should be updated.
On another note. You should use the strongly-typed Include(x => x.ProcessType) rather than Include("ProcessType").
In my model I have two classes Categories and Products. There is a relation many- to many between them.
I set states of all categories on modified manually and when I watched in the debugger before saveChanges() I saw that all of these categories were marked as modified. But after request mapping between categories and product weren't updated in my database. Code of update function.
public void UpdateProduct(Product product)
{
using (EFDbContext context = new EFDbContext())
{
context.Products.Attach(product);
if (product.Categories != null)
{
foreach (var item in product.Categories)
{
context.Entry(item).State = EntityState.Modified;
}
}
context.Entry(product).State = EntityState.Modified;
context.SaveChanges();
}
}
Setting entity to modified says that you have changed its properties (not navigation properties) and you want to save them. If you changed relations (navigation properties) by for example creating new relation between existing product and category or removing relation between existing product and category setting state to modified will not help you. This is actually very hard to solve (it is same in all current EF versions) because that relation has its own state which must be set and state of relation cannot be Modified = you must know if you added or removed relation. Especially removing is hard because you probably don't have information about relations you have removed from Categories navigation property when you are going to attach entity to the context. Moreover DbContext doesn't offer access to state of the relation so you must convert it to ObjectContext and use ObjectStateManager.
The easiest way to solve this issue is to load product with categories from database prior to saving and manually synchronize your detached object graph (the one you are trying to save at the moment) with loaded attached graph. Once you synchronize all changes in attached graph you will save it back to database. Attached graph will know which relations to categories were added or removed.
I got a problem with Entity Framework 4.0
I have a hierarchical table Category: Id, Name, ParentCategory_Id, timestamp
The "timestamp" field is marked as "Concurrency Mode" = "Fixed"
And I'm using Self-Tracking Entity "Category" to manage Category entity in my MVC application.
The situation:
I create STE "NewCategory",
set field Name='bla-bla'
create new STE "ParentCategory" like this:
var ParentCategory = new Category{Id=45};
ParentCategory.MarkAsUnchanged();
NewCategory.Parent = ParentCategory;
Call ApplyChanges() method in my STE Context and call SaveChanges()
The Query is "Update Category set Name=...." !!!!!!
If I do NewCategory.Parent = null OR set "Concurrncy Mode" = "Node" in model scheme everything works FINE.
How to use hierarchical data with concurrency check ?
I solved this problem.
The solution is that the EF4.0 could manage theese situations only if you will use FK Assotiation properties.
In this sample the right way to do:
1)Create self assotiation in Category entity in edmx model. In "Referential Constraint" create link with parent entity via ParentCategory_Id property.
2) Create new instance of Category STE.
3) Set relation:
NewCategory.ParentCategory_Id = 45;
4) ApplyChanges, SaveChanges.
I have an entity that has one child and I need to update it, but, in the TryUpdateModel method, it does not accept an strong typed object (accepts only a FormCollection), and when I try to update it, I get the following error.
{"A relationship is being added or deleted from an AssociationSet 'FK__SG_Usuari__ID_Si__534D60F1'. With cardinality constraints, a corresponding 'SG_Usuario' must also be added or deleted."}
The problem is that I can't load in the formcollection the child property, only an id, but not the entire object.
You can directly click update from model in entity framework and it will automatically update the enitty with all the relationship
the "create" statement is like this:
public ActionResult Edit(FormCollection form)
{
Usuario usuario = new Usuario
{
NomeUsuario = form["Usuario.NomeUsuario"],
IdeUsuario = form["Usuario.IdeUsuario"],
NumRegistroRM = form["Usuario.NumRegistroRM"],
SenUsuario = form["Usuario.SenUsuario"],
SituacaoUsuario = this.SituacaoUsuarioService.GetSituacaoUsuario(x => x.ID_SituacaoUsuario == Convert.ToInt32(form["Usuario.SituacaoUsuario"]// note that i have to retrieive the entire object... the "child"
};
this.UsuarioService.AddUsuario(usuario);
}
the edit statement should be like this:
TryUpdateModel(a, "Usuario", this.GetUsuarioWhiteList(), form.ToValueProvider()); // but the form contains only the id and I can't load the child in it nor pass the object.
I had the same issue recently and I managed to solve it when I changed the cardinality ratios for my foreign keys in the child table from 1:many to 0..1:many in the Entity Designer and it worked fine.