在更新实体框架上忽略一个属性

时间:2013-12-03 14:21:48

标签: .net entity-framework updates

我正在使用.NET C#和Entity Framework。

我有一种情况需要更新数据库中的对象,但我会保持一个属性不变。我想知道是否可以这样做?

以下面的课程为例:

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

因此,我会在页面中提供HTML表单,供客户端编辑人员。 示例:

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

然后我抓住这些值并发送到存储库以更新该Person。但是更新CreationDate是没有意义的,我不想提供这种可能性。

所以我可以用两种不同的方式做到这一点。

1)我可以将其作为隐藏字段放入表单中并将其发回。 (但正如我所说,我不想提供这种可能性)

2)在存储库中获取Person,更新它的字段并保持CreationDate日期相同然后保存:

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();        
}

我想知道一种方法,我可以将“p”传递给上下文并更新它,使CreationDate保持原样。

我希望我更清楚。

我很抱歉第一篇文章中缺少信息。

感谢您的帮助。

3 个答案:

答案 0 :(得分:3)

就个人而言,我使用AutoMapper并在您不想复制的一个字段上使用Ignore。这样,如果您向表中添加新列,则无需担心将它们添加到存储库。

所以,像这样......

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();        
}

答案 1 :(得分:1)

另外两种方法......

为SQL表添加默认值

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

使用支持字段,默认为DateTime.Now

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

    private DateTime createdDate = DateTime.Now;

答案 2 :(得分:0)

这就是我使用的,使用自定义InjectNonNull(obj dest,obj src),即使您有两个或多个字段,它也可以完全灵活

[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;
}
相关问题