Using Telerik OpenAccess ORM I have 2 objects User and Investment. More specifically Investments contains a foreign key to User as any typical one to many relationship. In other words each User can have mutliple Investments but each Investment can only have one user.
I have then attempted to utilize the open access feature 'Is Managed'
Which should mean that I can do something like User.Investments.Clear(); and it deletes all the related investments (or at least this works fine in many-to-many relationships) but unfortunately when I attempt this I am greeted with the following error.
"Update failed: Telerik.OpenAccess.RT.sql.SQLException: Cannot insert
the value NULL into column 'UserID', table
'CODECorp.dbo.Investment'; column does not allow nulls. UPDATE
fails."
Clearly what the ORM is trying to do is remove the association (i.e. foreign key) from the investment object to the user rather than deleting it. I have confirmed this by running SQL profiler and can see that it's running an Update rather than a Delete.
So what am I missing here? Why is it incorrectly trying to remove the association rather than simply deleting the row as you would expect?
By design, the behaviour of the navigation properties with IsManaged set to True, in scenarios where a child object is deleted from the collection of the parent object, is to remove the relationship between the two objects. In other words, Telerik Data Access (previously known as Telerik OpenAccess ORM) will keep the child record in the database but will generate a statement that attempts to set the foreign key to NULL.
A solution in this situation would be to pass the collection to the Delete method of the context. For example:
dbContext.Delete(User.Investments);
dbContext.SaveChanges();
This will produce the necessary DELETE statement. More details about the management of navigation properties with Telerik Data Access is available in this documentation article.
I hope you find this feasible. I am looking forward to your feedback.
Related
I'm setting up a data warehouse (in SQL Server) together with our engineers we got almost everything up and running. Our main application also uses SQL Server as backend, and aims to be code first while using the entity framework. In most tables we added a column like updatedAt to allow for incremental loading to our data warehouse, but there is a many-to-many association table created by the entity framework which we cannot modify. The table consists of two GUID columns with a composite key, so they are not iterable like an incrementing integer or dates. We are now basically figuring out the options on how to enable incremental load on this table, but there is little information to be found.
After searching for a while I mostly came across posts which explained how it's not possible to manually add columns (such as updatedAt) to the association table, such as here Create code first, many to many, with additional fields in association table. Suggestions are to split out the table into two one-to-many tables. We would like to prevent this if possible.
Another potential option would be to turn on change data capture on the server, but that would potentially defeat the purpose of code first in the application.
Another thought was to add a column in the database itself, not in code, with a default value of the current datetime. But that might also be impossible / non compatible with the entity framework, as well as defeating the code first principle.
Are we missing anything? Are there other solutions for this? The ideal solution would be a code first solution, or a solution in the ETL process without affecting the base application, without changing too much. Any suggestions are appreciated.
Well, I have tried to do a Many-to-Many relationship using Entity framework, where the Join table has more than just two ID, it will have two other columns Active and DateUpdate. So here is the designer.
Tables Design
When I did the context importing from an existing database, it look to work well. But I got a big question, is it right have the direction going from Group[0].GroupUser[0].User and going back in the same case? And in that way creating a lot of redundancy has showed in the picture below? Or is it something wrong?
Redundancy
It is not redundancy. Group[0].GroupUser[0].User is a reference to User and User has a navigation property to the GroupUser. Therefore, when you see User and then navigate to GroupUser of that user, the GroupUser will have a reference to User. If you keep expanding, it will keep showing you the same User and GroupUser.
I'm using ASP.NET WebApi 2 and loading in part of a relational database structure into the front end website. This allows the user to make changes to multiple tables in a single store and to also view some extra data.
This mostly works pretty well. It means I can store changes to, say a person table and their related clothes and hair color on one call as follows:
db.person.Add(person);
db.SaveChanges();
The problem is that, I don't want to load all the related data. So where the shoe table may be loaded, I don't want the laces table to load with info about laces.
The issue I'm running into is that there is an attempt to store a duplicate shoe table to the database even though this was only loaded to allow the user to view these details. I imagine that this is because, I'm using [JsonIgnore] attributes to ignore certain parts of the object - it is thus recognizing this as a new object, when it isn't.
I could loop through the object removing any shoe information before call Add, but this would be slow.
Perhaps it is best to post a second object that only includes the items that have changed (after tracking these in the front end). Is there a better way?
When you use DbSet<T>.Add() in EF, the entity (or all the entitis in the tree, if it's an entity with related child entities) is attached to the DbContext as Added. That means that when you call SaveChanges EF will try to insert all the objects in the database. That's why you're getting duplication problems.
You need to learn how to work in disconnected mode with EF. Basically you need to track the state of each entity (i.e. control if they have to be inserted, deleted or updated), and set the correct state when you attach the entities in the context.
Look for docs on working with disconnected entities in EF, for example:
Persistence in Entity Framework
Add, Attach and Entity States
These will explain you how to handle disconnected entities.
I need to write a plugin that iterates over a bunch of records inside a forms sub-grid. Previously the plugin checked a single lookup and performed some basic functions based on the value it held. Now the client wants multiple records to be linked to this record in an N:N relationship. I've seen this can be done in JavaScript but unfortunately this is no use to me. Can this be done in a plugin? If so, how?
Yes this can be done; and some methods of doing this are easier than others. As you noticed, the 1:N relationship is easy to manage from the child side through an EntityReference to the parent.
In the N:N relationship, you can retrieve the related entity using an approach like the one suggested in this article (not mine) about Retrieving Relationships
Another approach (depending on how you generated your code with the CrmSvcUtil):
<entity>.GetRelatedEntities<<related entity type>>("<Relationship Name>", null);
If the records inside the sub grid are linked with the main entity record, by having its GUID as parent ID, then you could use QueryExpression/QueryByAttribute to retrieve all the records in your subgrid and then iterate over them...
Okay. assume I have structure:
School -> students -> StudentParents <- parents -> address
School can have many students, students can be relatives and have the same set of parents (may-to-many). Each parent can have multiple addresses.
Assume that students who have the same set of parents cannot study in different schools.
If given school_Id =5, I want to remove this school and all related records.
How to do this easily in Entity Framework 4?
Answer for your question would be same as this question.
You are trying to solve the problem in the wrong layer. You need to
reconsider your database design specially how you maintain the
referential integrity.
You need to set the "CASCADE DELETE"s of the foreign keys and reflect
that in your Entity Model. Then the database will make the necessary
changes to maintain the referential integrity when you delete that
entity.
Entity framework cannot delete data from database that is not instantiated as object in memory. This means you would need to load school data, all students data, all students parent data and so on, and then you would need to manually delete all the data.
This seems like a lot of work to do, so you may want to take another approach to this problem - delete all this data using stored procedure on database that is mapped to ObjectContext, this would perform better since you would not need to get all the data into memory.
But this also seems troublesome. The best approach would be to create Cascade delete constrain on database and map it also in entity framework's model. This has two advantages - you would need to only load school data and after it is deleted from model, it would be deleted from database and cascade delete would remove all referencing data. But if you have school and students data already in memory, EF will take care of marking those objects from memory as deleted, which will make your data consistent with database state.
The best resolution to this problem depends on whether you may or may not modify database. If you can - go for cascade delete. If you cannot - I would recommend stored procedure approach as better performing (assuming performance is an issue and there is lots of students, parents etc. in database).