How do I attach and update an existing entity? - c#

I want to construct a disconnected object on my web page:
var entity = new MyEntity();
entity.ID = IdFromPage;
entity.Name = UpdatedNameFromPage;
Connect it to my object context and then call context.Save()
but how do I do this? I dont want to have to use linq to extract the entity like this...
var entityFromPage = new MyEntity();
entity.ID = IdFromPage;
entity.Name = UpdatedNameFromPage;
var connectedEntity = _db.MyEntities.Where(x => x.ID == IdFromPage).First();
connectedEntity.ID = entityFromPage.ID;
connectedEntity.Name = entityFromPage.Name;
Because the second part of this script may be massive and I dont want to have to re-map everything. I just want to slot it in on the ID and then call Save() is this possible?

You don't have to.
If you know it already exists on the database,
objectcontext.YourEntities.Attach(entity);
objectcontext.ObjectStateManager.ChangeObjectState(entity, EntityState.Modified);
objectcontext.SaveChanges();
(If it's a new entity, then you add it to the context)

Related

How to insert old record to new entity?

I am trying to check record , if exists declare to data with old one . But if doesnt then create a new one. Here is my code ;
var teamCheck= FootballerDBContext.Teams.Any(r => r.Name == teamName.Text.Trim());
if (teamCheck)
{
team = FootballerDBContext.Teams.FirstOrDefault(c => c.Name == teamName.Text);
}
FootballerDBContext.Teams.Add(team);
FootballerDBContext.SaveChanges(); // throwing exception right there . I did it exactly same to other entity everything was fine.
Here is other entity , i did the same but Team throws exception. No errors here , doing what i want. It doesnt create new entity with new ID , just declaring old one.
( sponsor has many-to-many relationship , team has one-to-many )
var sponsorCheck = FootballerDBContext.Sponsors.Any(x => x.Name == Sponsor.Text.Trim());
if (sponsorCheck)
{
sponsor = FootballerDBContext.Sponsors.FirstOrDefault(z => z.Name == Sponsor.Text);
}
FootballerDBContext.FootballerSponsor.Add(fbsp);
FootballerDBContext.SaveChanges();
Don't do it like you're doing; it queries the database twice
Do a pattern like this instead:
var team = FootballerDBContext.Teams.FirstOrDefault(c => c.Name == teamName.Text.Trim());
if(team == default) //or null
{
team = new Team(){ Name = teamName.Text };
FootballerDBContext.Teams.Add(team);
}
team.Location = teamLocation.Text;
...
FootballerDBContext.SaveChanges();
Query using Find or FirstOrDefault
If the result is null make a new one and assign it to the variable that is null
Add the team to the context if you just made a new one
Now you definitely have a team, either because you made it new or because it already exists and is looked up
You can set other properties
Call save changes at the end and an update or insert command will be run as appropriate
These LINQ queries are not the same:
teamName.Text.Trim() vs teamName.Text
.Trim()
try to check if variable is null or not like this:
string teamName = teamName.Text.Trim()
if (!String.IsNullOrEmpty(teamName))
first: **team** default value is (teamName)
second: validate linq query... r => r.Name == teamName
if (second == false)
save first.

.net MVC entity framework SaveChanges does not working

I want to update my db like
var context = new asb_cardEntities3();
var query = db.WFileMaster.Where(q => q.ID ==
data.ID).FirstOrDefault();
query.SUBE = item.SUBE.ToString();
query.HES_NO = item.HES_NO.ToString();
query.DVZ_KOD = item.DVZ_KOD.ToString();
query.TUTAR = item.TUTAR.ToString();
//context.Entry(query).State = SUBE.Modified;
context.SaveChanges();
this, I did not get any error (all data come) I am new in this framework, I think problem is in context. But I did not find any solution.
Please change db to context while retrieving the record in the second line.
var context = new asb_cardEntities3();
var query = context.WFileMaster.Where(q => q.ID == data.ID).FirstOrDefault();
query.SUBE = item.SUBE.ToString();
query.HES_NO = item.HES_NO.ToString();
query.DVZ_KOD = item.DVZ_KOD.ToString();
query.TUTAR = item.TUTAR.ToString();
context.SaveChanges();
Before saving changes update the table
something like that
.Update(x => x.Id== ID, object); and then
save changes.

The instance of entity type 'Product' cannot be tracked because another instance with the same key value is already being tracked

I made a test with code below to update the Product:
var existing = await _productRepository.FirstOrDefaultAsync(c => c.Id == input.Id);
if (existing == null)
throw new UserFriendlyException(L("ProductNotExist"));
var updatedEntity = ObjectMapper.Map<Product>(input);
var entity = await _productRepository.UpdateAsync(updatedEntity);
But it throws an exception:
Mvc.ExceptionHandling.AbpExceptionFilter - The instance of entity type 'Product' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached.
This is caused by querying existing. Is there any solution for this?
Since you are not using the existing entity, don't load it.
Use AnyAsync to check if it exists:
var exists = await _productRepository.GetAll().AnyAsync(c => c.Id == input.Id); // Change
if (!exists) // this
throw new UserFriendlyException(L("ProductNotExist"));
var updatedEntity = ObjectMapper.Map<Product>(input);
var entity = await _productRepository.UpdateAsync(updatedEntity);
If you want to map to the existing entity:
var existing = await _productRepository.FirstOrDefaultAsync(c => c.Id == input.Id);
if (existing == null)
throw new UserFriendlyException(L("ProductNotExist"));
var updatedEntity = ObjectMapper.Map(input, existing); // Change this
AsNoTracking() could help you.
Check the value of updatedEntity.Id, if it's zero then use the below code.
var updatedEntity = ObjectMapper.Map<Product>(input);
updatedEntity.Id = input.Id; //set Id manually
var entity = await _productRepository.UpdateAsync(updatedEntity);
add code for detaching
_dbcontext.Entry(oldEntity).State = EntityState.Detached;

EntityFramework update partial model

I am working on mvc project, with repository pattern and entity framework, now on my form i have a sample model
SampleModel
1) name
2) age
3) address
4) notes
5) date updated
I am displaying only following data on the edit form
1) name
2) age
3) address
now if i update the model with missing property values using the repository, the notes, dateupdated field goes null.
My question is how do i update only few selected properties using the repository ( tryupdatemodel not available in repository ) and i dont want to call the original object and map the properites with the updated model.
Is there any way, there must be.
You can update only subset of fields:
using (var context = new YourDbContext())
{
context.SamepleModels.Attach(sampleModel);
DbEntityEntry<SameplModel> entry = context.Entry(sampleModel);
entry.Property(e => e.Name).IsModified = true;
entry.Property(e => e.Age).IsModified = true;
entry.Property(e => e.Address).IsModified = true;
context.SaveChanges();
}
or in ObjectContext API:
using (var context = new YourObjectContext())
{
context.SamepleModels.Attach(sampleModel);
ObjectStateEntry entry = context.ObjectStateManager.GetObjectStateEntry(sampleModel);
entry.SetModifiedProperty("Name");
entry.SetModifiedProperty("Age");
entry.SetModifiedProperty("Address");
context.SaveChanges();
}
This is an old thread, but if anyone is interested, to extend on Ladislav's solutions, we've come up with a helpful extension method for EF 4.1 and newer:
public static void SetModified<TEntity>(
this DbEntityEntry<TEntity> entry,
IEnumerable<Expression<Func<TEntity, object>>> expressions) where TEntity : class, IEntity
{
foreach (var expression in expressions)
entry.Property(expression).IsModified = true;
}
Obviously you'll need to take away the IEntity constraint unless you're using an interface by the same name for your POCOs.
Example usage would be:
var user = new User
{
Id = Request.Id,
UserName = Request.UserName,
FirstName = Request.FirstName
};
var expressions = new List<Expression<Func<User, object>>>
{
x => x.UserName,
x => x.FirstName
};
context.Entry(user).SetModified(expressions);

LINQ - How can I give a child object in a select statement a reference to its parent?

I'm trying to do something like this:
List<FundEntity> entities = this.tFunds
.Select(f => new FundEntity() {
ID = f.fundID,
Name = f.name,
CapitalCalls = f.tCapitalCalls
.Select(cc => new CapitalCall() {
ID = cc.capitalCallID,
Description = cc.description,
FundEntity = // Should be the newly created Fund Entity object
}).ToList()
}).ToList();
I would like the each Capitalcall object to have a reference back to its FundEntity. Is this possible without creating a loop and setting each one manually?
List<FundEntity> entities = this.tFunds
.Select(f =>
{
var parent = new FundEntity() {
ID = f.fundID,
Name = f.name,
};
parent.CapitalCalls = f.tCapitalCalls
.Select(cc => new CapitalCall() {
ID = cc.capitalCallID,
Description = cc.description,
FundEntity =parent // Should be the newly created Fund Entity object
});
return parent;
}.ToList()
).ToList();
That should give you the reference.
Is this LINQ in memory or LINQ to Entities/SQL?
In the first case, you can just create the entity and then set its CapitalCalls property imperatively (as in the example from Stephan)
In the second case, I'm afraid there is no way to do this in the LINQ query (because you cannot reference to the object that you're creating while it is being created, but you cannot use multiple statements, because the translator doesn't support that). However you could easily modify your database or Entity model to contain the reference you need...

Categories