Entity framework: writting custom data annotaions to change CASE of values
class DemoUser
{
[TitleCase]
public string FirstName { get; set; }
[TitleCase]
public string LastName { get; set; }
[UpperCase]
public string Salutation { get; set; }
[LowerCase]
publ开发者_如何学Goic string Email { get; set; }
}
Suppose i have demo-class as written above, i want to create some custom annotations like LowerCase,UpperCase etc so that its value gets converted automatically. Doing this will enable me to use these annotations in other classes too.
As Ladislav implied, this is two questions in one.
Assuming you follow the recipe for creating attributes in Jefim's link, and assuming you're calling those created attribute classes "UpperCaseAttribute", "LowerCaseAttribute", and "TitleCaseAttribute", the following SaveChanges() override should work in EF 4.3 (the current version as of the time of this answer post).
public override int SaveChanges()
{
IEnumerable<DbEntityEntry> changedEntities = ChangeTracker.Entries().Where(e => e.State == System.Data.EntityState.Added || e.State == System.Data.EntityState.Modified);
TextInfo textInfo = Thread.CurrentThread.CurrentCulture.TextInfo;
changedEntities.ToList().ForEach(entry =>
{
var properties = from attributedProperty in entry.Entity.GetType().GetProperties()
where attributedProperty.PropertyType == typeof (string)
select new { entry, attributedProperty,
attributes = attributedProperty.GetCustomAttributes(true)
.Where(attribute => attribute is UpperCaseAttribute || attribute is LowerCaseAttribute || attribute is TitleCaseAttribute)
};
properties = properties.Where(p => p.attributes.Count() > 1);
properties.ToList().ForEach(p =>
{
p.attributes.ToList().ForEach(att =>
{
if (att is UpperCaseAttribute)
{
p.entry.CurrentValues[p.attributedProperty.Name] = textInfo.ToUpper(((string)p.entry.CurrentValues[p.attributedProperty.Name]));
}
if (att is LowerCaseAttribute)
{
p.entry.CurrentValues[p.attributedProperty.Name] = textInfo.ToLower(((string)p.entry.CurrentValues[p.attributedProperty.Name]));
}
if (att is TitleCaseAttribute)
{
p.entry.CurrentValues[p.attributedProperty.Name] = textInfo.ToTitleCase(((string)p.entry.CurrentValues[p.attributedProperty.Name]));
}
});
});
});
return base.SaveChanges();
}
You can override the SaveChanges
method in your EF context (if you use default code-generation just write a partial class). Something like the following:
public partial class MyEntityContext
{
public override int SaveChanges(SaveOptions options)
{
IEnumerable<ObjectStateEntry> changedEntities =
this.ObjectStateManager.GetObjectStateEntries(
System.Data.EntityState.Added | System.Data.EntityState.Modified);
// here you can loop over your added/changed entities and
// process the custom attributes that you have
return base.SaveChanges(options);
}
}
精彩评论