Entity Framework,以任何实体作为参数的方法(如何使代码更通用)

Entity Framework, Method with any entity as parameter (How to make code more generic)

我有一个将上下文和实体对象作为参数的方法。 此方法应该能够确定任何 class(table) 的公共 属性(我的代码中的 COID)是否具有值。

我找不到重写这段代码的方法,因此它更通用,目前我正在检查传递给该方法的每个实体的类型。

    public async static Task<bool> IsCOIDAssigned(ProjectEntities _context, object _entity)
    {
        var bSuccess = false;

        //First type to check
        if (_entity is tblLine)
        {
            var _line = _entity as tblLine;
            await _context.Entry(_entity).ReloadAsync().ContinueWith(x =>
            {
                if (!x.IsFaulted)
                {
                    var query = from c in _context.tblLines
                                where c.ID.Equals(_line.ID)
                                select c;
                    if(query.Single().COID.GetValueOrDefault() == 0)
                    {
                        Console.WriteLine("Not assigned");
                        bSuccess = true;
                    }  
                    else
                    {
                        Console.WriteLine("Assigned");
                        bSuccess = false;
                    }
                }
                else
                {
                    bSuccess = false;
                }
            }, TaskScheduler.FromCurrentSynchronizationContext());
        };

        //Second type to check
        if (_entity is tblDevice)
        {
            var _device = _entity as tblDevice;
            await _context.Entry(_entity).ReloadAsync().ContinueWith(x =>
            {
                if (!x.IsFaulted)
                {
                    var query = from c in _context.tblDevices
                                where c.ID.Equals(_device.ID)
                                select c;

                    if (query.Single().COID.GetValueOrDefault() == 0)
                    {
                        Console.WriteLine("Not assigned");
                        bSuccess = true;
                    }
                    else
                    {
                        Console.WriteLine("Assigned");
                        bSuccess = false;
                    }
                }
                else
                {
                    bSuccess = false;
                }

            }, TaskScheduler.FromCurrentSynchronizationContext());
        };


        //Third type to check ....
        //Fourth type to check ....

        return bSuccess;
    }

有没有人看到更好的解决方案?

您可以为至少包含属性 COID 和 Id 的 tblLine 和 tblDevice 创建基本抽象 class。

public abstract class TblBase
{
    public int Id { get; set; }

    public int COID { get; set; }

    //other common properties
}

public class TblLine : TblBase
{
    // properties
}

public class TblDevice : TblBase
{
    // properties
}

因此在您的上下文中您将拥有:

public DbSet<TblBase> TblBases { get; set; }

您必须为两个 classes 设置继承到 TPC (Table-per-Concrete-Type):

modelBuilder.Entity<TblLine>().Map(m =>
{
    m.MapInheritedProperties();
    m.ToTable("tblLines");
});

modelBuilder.Entity<TblDevice>().Map(m =>
{
    m.MapInheritedProperties();
    m.ToTable("tblDevices");
});

然后就可以使用context.TblBases查询数据了

我按照 arekzyla 的解决方案使我的 tables 继承了 tblBase。 但是,因为我有一个 database-first 模型,所以无法通过代码修改我的模型(不确定这是否可能?)

多亏了 arekzyla,我设法得到了我想要的东西,但是由于涉及的 linq 查询较少,我将我的实体转换为 TblBase,它是一个 class 包含 ID 和 COID(常见 table 属性。)

public static async Task<bool> IsEntityCheckedOut(ProjectEntities _context, object _entity)
    {
        var bCheckedOut = false;
        await _context.Entry(_entity).ReloadAsync().ContinueWith(x =>
        {
            if (!x.IsFaulted)
            {
                var _baseentity = _entity as TblBase;
                if (_baseentity.COID.GetValueOrDefault() != 0)
                {
                    Console.WriteLine("Assigned");
                    bCheckedOut = true;
                }
                else
                {
                    Console.WriteLine("Not Assigned");
                }
            }
        }, TaskScheduler.FromCurrentSynchronizationContext());
        return bCheckedOut;
    }