开发者

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜