我正在使用.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保持原样。
我希望我更清楚。
我很抱歉第一篇文章中缺少信息。
感谢您的帮助。
答案 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;
}