开发者

Entity Framework 4: Any way to know the plural form of an Entity Type?

Given this code:

private ObjectQuery<E> GetEntity()
{   // Pluralization concern.  Table and Type need to be consistently named.
    // TODO: Don't get cute with database table names.  XXX and XXXs for pluralization
    return 开发者_运维技巧_dc.CreateQuery<E>("[" + typeof(E).Name + "s]");
}

Is there any way to determine an Entity type's plural name so I can access the table, rather than just adding an 's' to the name?

For example, Medium is singular and Media is plural.


You can also use the PluralizationService provided by EF 4. Here is a blog post that covers the service in good detail.

http://web.archive.org/web/20130521044050/http://www.danrigsby.com/blog/index.php/2009/05/19/entity-framework-40-pluralization


I'm not sure how entity framework does this, but I use the pluralizer from Ruby on Rails. You can find this at http://dev.rubyonrails.org/browser/trunk/activesupport/lib/active_support/inflector.rb#L106. This is easy enough to implement in C#.

The entire source for a translation to C# is:

using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

public static class Inflector
{
    private static List<KeyValuePair<Regex, string>> _pluralRules = new List<KeyValuePair<Regex, string>>();
    private static List<KeyValuePair<Regex, string>> _singularRules = new List<KeyValuePair<Regex, string>>();
    private static List<KeyValuePair<string, string>> _irregulars = new List<KeyValuePair<string, string>>();
    private static List<string> _uncountables = new List<string>();

    static Inflector()
    {
        _uncountables.Add("equipment");
        _uncountables.Add("information");
        _uncountables.Add("rice");
        _uncountables.Add("money");
        _uncountables.Add("species");
        _uncountables.Add("series");
        _uncountables.Add("fish");
        _uncountables.Add("sheep");

        AddPlural("$", "s", true);
        AddPlural("s$", "s");
        AddPlural("(ax|test)is$", "$1es");
        AddPlural("(octop|vir)us$", "$1i");
        AddPlural("(alias|status)$", "$1es");
        AddPlural("(bu)s$", "$1ses");
        AddPlural("(buffal|tomat)o$", "$1oes");
        AddPlural("([ti])um$", "$1a");
        AddPlural("sis$", "ses");
        AddPlural("(?:([^f])fe|([lr])f)$", "$1$2ves");
        AddPlural("(hive)$", "$1s");
        AddPlural("([^aeiouy]|qu)y$", "$1ies");
        AddPlural("(x|ch|ss|sh)$", "$1es");
        AddPlural("(matr|vert|ind)(?:ix|ex)$", "$1ices");
        AddPlural("([m|l])ouse$", "$1ice");
        AddPlural("^(ox)$", "$1en");
        AddPlural("(quiz)$", "$1zes");

        AddSingular("s$", "");
        AddSingular("(n)ews$", "$1ews");
        AddSingular("([ti])a$", "$1um");
        AddSingular("((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$", "$1$2sis");
        AddSingular("(^analy)ses$", "$1sis");
        AddSingular("([^f])ves$", "$1fe");
        AddSingular("(hive)s$", "$1");
        AddSingular("(tive)s$", "$1");
        AddSingular("([lr])ves$", "$1f");
        AddSingular("([^aeiouy]|qu)ies$", "$1y");
        AddSingular("(s)eries$", "$1eries");
        AddSingular("(m)ovies$", "$1ovie");
        AddSingular("(x|ch|ss|sh)es$", "$1");
        AddSingular("([m|l])ice$", "$1ouse");
        AddSingular("(bus)es$", "$1");
        AddSingular("(o)es$", "$1");
        AddSingular("(shoe)s$", "$1");
        AddSingular("(cris|ax|test)es$", "$1is");
        AddSingular("(octop|vir)i$", "$1us");
        AddSingular("(alias|status)es$", "$1");
        AddSingular("^(ox)en", "$1");
        AddSingular("(vert|ind)ices$", "$1ex");
        AddSingular("(matr)ices$", "$1ix");
        AddSingular("(quiz)zes$", "$1");

        AddIrregular("person", "people");
        AddIrregular("man", "men");
        AddIrregular("child", "children");
        AddIrregular("sex", "sexes");
        AddIrregular("move", "moves");
        AddIrregular("cow", "kine");
    }

    private static void AddIrregular(string singular, string plural)
    {
        AddPlural(singular.Substring(0, 1).ToLower() + singular.Substring(1) + "$", plural.Substring(0, 1).ToLower() + plural.Substring(1));
        AddPlural(singular.Substring(0, 1).ToUpper() + singular.Substring(1) + "$", plural.Substring(0, 1).ToUpper() + plural.Substring(1));
        AddSingular(plural.Substring(0, 1).ToLower() + plural.Substring(1) + "$", singular.Substring(0, 1).ToLower() + singular.Substring(1));
        AddSingular(plural.Substring(0, 1).ToUpper() + plural.Substring(1) + "$", singular.Substring(0, 1).ToUpper() + singular.Substring(1));
    }

    private static void AddPlural(string expression, string replacement)
    {
        AddPlural(expression, replacement, false);
    }

    private static void AddPlural(string expression, string replacement, bool caseSensitive)
    {
        var re = caseSensitive ? new Regex(expression) : new Regex(expression, RegexOptions.IgnoreCase);

        _pluralRules.Insert(0, new KeyValuePair<Regex, string>(re, replacement));
    }

    private static void AddSingular(string expression, string replacement)
    {
        AddSingular(expression, replacement, false);
    }

    private static void AddSingular(string expression, string replacement, bool caseSensitive)
    {
        var re = caseSensitive ? new Regex(expression) : new Regex(expression, RegexOptions.IgnoreCase);

        _singularRules.Insert(0, new KeyValuePair<Regex, string>(re, replacement));
    }

    public static string Pluralize(string value)
    {
        if (_uncountables.Contains(value))
            return value;

        foreach (var rule in _pluralRules)
        {
            if (rule.Key.Match(value).Success)
            {
                return rule.Key.Replace(value, rule.Value);
            }
        }

        return value;
    }

    public static string Singularize(string value)
    {
        if (_uncountables.Contains(value))
            return value;

        foreach (var rule in _singularRules)
        {
            if (rule.Key.Match(value).Success)
            {
                return rule.Key.Replace(value, rule.Value);
            }
        }

        return value;
    }

    public static string Camelize(string value, bool firstLetterUppercase = true)
    {
        if (firstLetterUppercase)
        {
            return
                Regex.Replace(
                    Regex.Replace(value, "/(.?)", p => "::" + p.Groups[1].Value.ToUpperInvariant()),
                    "(?:^|_)(.)", p => p.Groups[1].Value.ToUpperInvariant()
                );
        }
        else
        {
            return
                value.Substring(0, 1).ToLowerInvariant() +
                Camelize(value.Substring(1));
        }
    }

    public static string Underscore(string value)
    {
        value = value.Replace("::", "/");
        value = Regex.Replace(value, "([A-Z]+)([A-Z][a-z])", p => p.Groups[1].Value + "_" + p.Groups[2].Value);
        value = Regex.Replace(value, "([a-z\\d])([A-Z])", p => p.Groups[1].Value + "_" + p.Groups[2].Value);
        value = value.Replace("-", "_");

        return value.ToLowerInvariant();
    }
}


Have you tried

YourEntityObject.EntityKey.EntitySetName

Assuming your table names are plural.

If the generic method you have takes an entity (that inherits from EntityObject), then you can access the EntityKey from it.

private ObjectQuery<E> GetEntity()
{   // Pluralization concern.  Table and Type need to be consistently named.
    // TODO: Don't get cute with database table names.  XXX and XXXs for pluralization
    return _dc.CreateQuery<E>("[" + e.EntityKey.EntitySetName + "]");
}
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜