Ignore one property on update Entity Framework

情到浓时终转凉″ 提交于 2019-12-24 05:22:25

问题


I'm working with .NET C# and Entity Framework.

I have a situation where I need to update an object in the database but I'll keep one property untouched. I'd like to know is it possible to do that?

Take the following class for example:

public class Person
{
    public int PersonId { get; set; }
    public string Name{ get; set; }
    public int Age { get; set; }
    public DateTime CreationDate { get; set; }
}

So I would provide a HTML form in a page for the client to edit a person. Example:

<form>
    <input type="hidden" id="PersonId" value="1" />
    <input type="text" id="Name" value="Cesar" />
    <input type="text" id="Age " value="28" />
</form>

Then I'd grab the values and send to the repository to update that Person. But it does not make sense updating CreationDate, and I don't want to provide that possibility.

So I could do it in 2 different ways.

1) I could put it in the form as a hidden field and post it back. (but as I said I don't want to provide that possibility)

2) In the repository get the Person, update it's fields and leave CreationDate date the same and then save it:

void UpdatePerson(Person p){
    var person = db.Persons.Find(PersonId);

    person.Name = p.Name;
    person.Age = p.Age;

    db.Persons.Attach(person);
    db.Entry(person).State = EntityState.Modified;
    db.SaveChanges();        
}

I'd like to know a way that I could just pass "p" to the context and update it leaving CreationDate the way it is.

I hope I was clearer.

I'm sorry about the lack of information in the first post.

Thank you for your help.


回答1:


Personally, I use AutoMapper and use Ignore on the one field you don't want to copy. This way, if you ever add new columns to the table, you don't have to worry about adding them to your repository.

So, something like this...

void UpdatePerson(Person p) {
    var person = db.Persons.Find(PersonId);

    Mapper.CreateMap<Person, Person>()
        .ForMember(dest => dest.CreationDate, opt => opt.Ignore());
    Mapper.Map(p, person);        

    db.SaveChanges();        
}



回答2:


Two other methods...

add a default to your SQL table

ALTER TABLE dbo.Person ADD CONSTRAINT
DF_Person_CreatedDate DEFAULT GetDate() FOR CreatedDate

use a backing field and default that to DateTime.Now

    public DateTime CreatedDate
    {
        get { return createdDate; }
        set { createdDate = value); }
    }

    private DateTime createdDate = DateTime.Now;



回答3:


This is what I use, using custom InjectNonNull (obj dest, obj src) it makes it fully flexible, even if you have two or more fields

[HttpPost]
public async Task<IActionResult> Post( [FromQuery]Models.Currency currency ) {
  if ( ModelState.IsValid ) {
    // find existing object by Key
    Models.Currency currencyDest = context.Currencies.Find( currency.Id ); 

    context.Currencies.Attach( currencyDest );

    // update only not null fields
    InjectNonNull( currencyDest, currency );

    // save
    await context.SaveChangesAsync( );
  }  
  return Ok();
}

// Custom method
public static T InjectNonNull<T>( T dest, T src ) {
  foreach ( var propertyPair in PropertyLister<T, T>.PropertyMap ) {
    var fromValue = propertyPair.Item2.GetValue( src, null );
    if ( fromValue != null && propertyPair.Item1.CanWrite ) {
       propertyPair.Item1.SetValue( dest, fromValue, null );
    }
  }
  return dest;
}


来源:https://stackoverflow.com/questions/20353665/ignore-one-property-on-update-entity-framework

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!