有什么方法可以验证全局唯一列值[Entity Framework]

时间:2019-11-04 06:13:55

标签: entity-framework linq-to-entities

我在数据库中有100多个表,其中60多个表包含名为ShortCode nvarchar(12)的列,它们代表该记录的全局唯一代码。

现在有任何方法可以找到ShortCode值,例如。 AST_SHIP_FIRE存在于数据库的任何表中。

注意ShortCode是用户定义的。

目前,我正在尝试以下代码,它可以工作,但是我必须为所有表编写代码。

if (entities.Table1.Any(x =>  x.ShortCode.Trim().ToLower() == a.ShortCode.Trim().ToLower()) 
{return false;}
else if(entities.Table2.Any(x => x.ShortCode.Trim().ToLower() == a.ShortCode.Trim().ToLower()))
{return false;}
else if( entities.Talble3.Any(x => x.ShortCode.Trim().ToLower() == a.ShortCode.Trim().ToLower()))
{return false;}
.
.
.
else
{
//insert code
}

我认为可能会有更有效的方法。

1 个答案:

答案 0 :(得分:2)

好吧,也许不是很简单,但是让我们做吧!

首先为ShortCode属性定义一个接口,并由拥有该属性的任何实体来实现:

public interface ITableWithShortCode
{
    public string ShortCode { get; set; }
}

public class Table1 : ITableWithShortCode
{
    public long Id { get; set; }
    public string ShortCode { get; set; }
}

public class Table2 : ITableWithShortCode
{
    public long Id { get; set; }
    public string ShortCode { get; set; }
}

现在使用Reflection的幂,您可以编写如下方法:

public bool IsExistShortCode(string shortCode)
{
    using (var context = new AppDbContext())
    {
        /* 
           find all tables that are defined in your DbContext and are implemented ITableWithShortCode like:
           public DbSet<Table1> Table1 { get; set; }
           public DbSet<Table2> Table2 { get; set; }
           ...
        */
        var properties = typeof(AppDbContext).GetProperties()
            .Where(p => p.PropertyType.IsGenericType
                && typeof(ITableWithShortCode).IsAssignableFrom(p.PropertyType.GenericTypeArguments[0]));

        foreach (var property in properties)
        {
            var contextProp = (IQueryable<ITableWithShortCode>)property.GetValue(context);
            bool isExist = contextProp.Any(p => p.ShortCode == shortCode);
            if (isExist)
                return true;
        }

        return false;
    }
}

注意:您可以对此代码进行一些优化,我更喜欢将其保持在最简单的状态以显示该想法。但是在生产中,例如,您可以轻松地在启动时缓存DbContext属性,然后在以后使用它