How can I insert and update foreign key table rows in efcore - entity-framework-core

The database operation was expected to affect 1 row(s), but actually affected 0 row(s); data may have been modified or deleted since entities were loaded. See http://go.microsoft.com/fwlink/?LinkId=527962 for information on understanding and handling optimistic concurrency exceptions.
agentDetail.AgentGDS_AccessDetails.ForEach(x => x.Deleted = false); //Update the record in table
agentDetailView.AgentGDS_AccessDetails
.ForEach(agentGDS_AccessDetailView =>
{
AgentGDS_AccessDetail agentGDS_AccessDetail = new AgentGDS_AccessDetail();
agentGDS_AccessDetail.GDS_AccessId = Guid.NewGuid();
agentGDS_AccessDetail.GDS_Id = agentGDS_AccessDetailView.GDS_Id;
agentGDS_AccessDetail.PCC = agentGDS_AccessDetailView.PCC;
agentGDS_AccessDetail.Description = agentGDS_AccessDetailView.Description;
agentDetail.AgentGDS_AccessDetails.Add(agentGDS_AccessDetail); //add the new record to table
});
_unitOfWork.Complete();//I can't able to update the record. it throws error

Related

Prevent duplicate values on bulk insert (Salesforce)

I need a trigger that receives data from users (Bulk load of about 1000 records) and store them in a Salesforce database. The problem is that users can show up more than once in Trigger.new or even on a different batch. The custom object name is CBK_User and has an EXTERNAL_ID (unique) called USER_ID. In my code I check that the users does not yet exist in the database:
Map<String, CBK_User__c> users = new Map<String,CBK_User__c>
([select Id, USER_ID__c from CBK_User__c where USER_ID__c in : userIds]);
(userIds has the external ids of the Trigger.new objects)
When a I try to insert, it gives me the error:
DUPLICATE_VALUE, duplicate value found: USER_ID__c duplicates value on
record with id: a1QJ0000000HRd8"
How do I prevent duplicate values on bulk insert?
I've adapted your problem to this basic example (Exercise 2: Lead duplicate prevention)
You should clean first the "new" list from duplicated entries, and then clean from existing in db.
trigger CBK_UserDuplicatePreventer on CBK_User__c (before insert, before update) {
//Enter a map declaration to hold records which we will add,
// this will become a unique map, no duplicate values within it.
Map<String, CBK_User__c> cbkUserMap = new Map<String, CBK_User__c>();
//The next few lines loop across the array of records that are passed into
//the trigger in bulk fashion from any API or User Interface database operation.
//The goal of this loop is to ensure that there are no duplicates within
//the batch that we have received and to gather a list of externalIds that we will use later
for (CBK_User__c cbkUser : System.Trigger.new) {
/* Make sure we don't treat an externalId that
isn't changing during an update as a duplicate. */
if ((cbkUser.USER_ID__c != null) && (System.Trigger.isInsert ||
(cbkUser.USER_ID__c != System.Trigger.oldMap.get(cbkUser.Id).USER_ID__c))) {
// Make sure another new CBK_User__c isn't also a duplicate
if (cbkUserMap.containsKey(cbkUser.USER_ID__c)) {
cbkUser.USER_ID__c.addError('Another new CBK_User__c has the same USER_ID.');
} else {
cbkUserMap.put(cbkUser.USER_ID__c, cbkUser);
}
}
}
// Using a single database query, find all the CBK_User__c in
// the database that have the same USER_ID as ANY
// of the CBK_User__c being inserted or updated. */
for (CBK_User__c cbkUser : [SELECT USER_ID__c FROM CBK_User__c WHERE USER_ID__c IN :cbkUserMap.KeySet()]) {
CBK_User__c newCbkUser = cbkUserMap.get(cbkUser.USER_ID__c);
newCbkUser.USER_ID__c.addError('A CBK_User__c with this USER_ID already exists.');
}
}

Sybase ASE Entity Framework - Error while updateing record to database -"incorrect syntax near '('.\n"

I am trying to simple update and existing record. And I am getting the error - incorrect syntax near '('.\n
Entities db = new Entities();
try
{
var existingObj = new OBJETE
{
OB_ID_MR = 348,
OB_ID_JE = 1156,
OB_IS_NT = false,
OB_ID_MS = 88,
OB_POSITIONABS = "12,12,12,12",
OB_ORDRE = 1,
OB_UPDATEDATE = DateTime.Now
};
db.OBJETEs.Attach(existingObj);
db.ObjectStateManager.ChangeObjectState(existingObj, System.Data.EntityState.Modified);
db.SaveChanges();
If I try to update "not null" columns then I can update the records in this table. But when I try to update nullable values then I am getting this error consistently. Please advice.
Found it! My Table did not have a Primary Key. Entity Framework add some addition tag to disable update of such tables.
So either you add a primary key to the table or if that is not an option like in my case the work around is to open the edmx file in Text mode, and remove the entry for the tag - "DefiningQuery" and all its contents for the Table in question. Additionally we need to change => store:Schema="dbo" to Schema="dbo" for that Table. This should fix the issue.

Entity Framework Insert, Update, Delete During Same Transaction

I have a problem, I have a wizard that can update data AND insert data. So, if I have an existing list of team members, I can update their roles but If necessary, I can also add/insert a person to this team. So I can update roles and insert a new team member into the same table all during the same transaction. Data can be updated to and inserted to table teamMembers.
When I try to add a new teamMember, I also have an existing member where I simply want to update his role.
Both changes happen to the same table called TeamMember. When I debug the context, everything looks good. it shows that there are two changes that will occur for the TeamMember table. One transaction is the update and the other transaction is the insert. When I perform an update using:
var teamMember = new TeamMember
{
Name = user.FullName,
UserProfileId = user.UserProfileId,
RoleId = user.RoleId
};
TeamMemberList.Add(teamMember);
project.TeamMembers = TeamMemberList;
//And then call
this.Context.Projects.Attach(project);
this.Context.Entry(project).State = System.Data.EntityState.Modified;
it updates but the record that needs to be inserted fails.
HOW CAN I DO BOTH AN INSERT AND UPDATE TO THE SAME TABLE DURING THE SAME TRANSACTION?
CURRENT ERROR IS:
The changes to the database were committed successfully, but an error occurred while updating the object context. The ObjectContext might be in an inconsistent state. Inner exception message: A referential integrity constraint violation occurred: The property values that define the referential constraints are not consistent between principal and dependent objects in the relationship.
I think you need to add the TeamMember entity to the context's global list. Something like:
var teamMember = new TeamMember()
{
Name = user.FullName,
UserProfileId = user.UserProfileId,
RoleId = user.RoleId
}
project.TeamMembers.Add( teamMember );
this.Context.TeamMembers.Add( teamMember );
this.Context.SaveChanges();
How about loading the existing project entity first and then adding members.
var project = this.Context.Project.Where(p => p.ID = "bar").Include("TeamMembers").FirstOrDefault();
var teamMember= new TeamMember
{
Name = user.FullName,
UserProfileId = user.UserProfileId,
RoleId = user.RoleId
};
project.TeamMembers.Add(teamMember);
this.Context.SaveChanges()

Implementing if-not-exists-insert using Entity Framework without race conditions

Using LINQ-to-Entities 4.0, is there a correct pattern or construct for safely implementing "if not exists then insert"?
For example, I currently have a table that tracks "user favorites" - users can add or remove articles from their list of favorites.
The underlying table is not a true many-to-many relationship, but instead tracks some additional information such as the date the favorite was added.
CREATE TABLE UserFavorite
(
FavoriteId int not null identity(1,1) primary key,
UserId int not null,
ArticleId int not null
);
CREATE UNIQUE INDEX IX_UserFavorite_1 ON UserFavorite (UserId, ArticleId);
Inserting two favorites with the same User/Article pair results in a duplicate key error, as desired.
I've currently implemented the "if not exists then insert" logic in the data layer using C#:
if (!entities.FavoriteArticles.Any(
f => f.UserId == userId &&
f.ArticleId == articleId))
{
FavoriteArticle favorite = new FavoriteArticle();
favorite.UserId = userId;
favorite.ArticleId = articleId;
favorite.DateAdded = DateTime.Now;
Entities.AddToFavoriteArticles(favorite);
Entities.SaveChanges();
}
The problem with this implementation is that it's susceptible to race conditions. For example, if a user double-clicks the "add to favorites" link two requests could be sent to the server. The first request succeeds, while the second request (the one the user sees) fails with an UpdateException wrapping a SqlException for the duplicate key error.
With T-SQL stored procedures I can use transactions with lock hints to ensure a race condition never occurs. Is there a clean method for avoiding the race condition in Entity Framework without resorting to stored procedures or blindly swallowing exceptions?
You can also write a stored procedure that uses some new tricks from sql 2005+
Use your combined unique ID (userID + articleID) in an update statement, then use the ##RowCount function to see if the row count > 0 if it's 1 (or more), the update has found a row matching your userID and ArticleID, if it's 0, then you're all clear to insert.
e.g.
Update tablex set userID = #UserID, ArticleID = #ArticleID (you could have more properties here, as long as the where holds a combined unique ID) where userID = #UserID and ArticleID = #ArticleID
if (##RowCount = 0)
Begin
Insert Into tablex ...
End
Best of all, it's all done in one call, so you don't have to first compare the data and then determine if you should insert. And of course it will stop any dulplicate inserts and won't throw any errors (gracefully?)
You could try to wrap it in a transaction combined with the 'famous' try/catch pattern:
using (var scope = new TransactionScope())
try
{
//...do your thing...
scope.Complete();
}
catch (UpdateException ex)
{
// here the second request ends up...
}

Entity Frmwk pb: search for 'added' entities in current context

I'm using guids as PK for my entities.
As EF doesn't support the newid() SQL statement, I force a Guid.NewGuid() in my creation methods.
Here is my problem :
I've a table with a clustered unique constraint (2 strings, not PK).
I'm running some code in the same EF context which perfoms operations and adds/links entities, etc.
Is it possible to search for an entity in 'Added' state in my context ? ; that is to say which is in my context, but not yet inserted in my DB.
To avoid the raising of the SQL unique constraint, I have to know if the entity is already 'queued' in the context, and to re-use it instead of creating a new Guid (... and a different entity! :( )
this post saved me :) :
Link
var stateEntries = context.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EtityState.Modified | EntityState.Unchanged);
var roleEntityEntries = stateEntries.Select(s => s.Entity).OfType<Role>();
roleEntity = roleEntityEntries.FirstOrDefault(r => r.RoleName.Trim().ToLower() == roleName.Trim().ToLower());
if (roleEntity == null)
{
return new Role { RoleName = roleName };
}