具有变量表和列名的实体框架6 .add()

时间:2018-12-05 05:25:02

标签: asp.net entity-framework webforms entity-framework-6

通过下面的简化示例,我可以获得一个有点动态的Entity Framework搜索结果,该示例从数据库或缓存中提取单个结果:

    string strTableName = "TableName2"
    string strColumnName = "MyColumnName"
    int intPrimaryKey = 1

    Type returnType;
    returnType = typeof(TableName1);
    string queryResults = null;
    switch (strTableName)
    {
        case "TableName2":
            returnType = typeof(TableName2);
            break;
    }

    var refColumnName = returnType.GetProperty(strColumnName );
    var query = mydbEntity.Set(returnType).Find(intPrimaryKey );
    var queryResults = refColumnName.GetValue(query).ToString();

这也可以用于更新记录:

        DataQuery.LeadsEntity.Entry(query).Property(strColumnName ).CurrentValue = "Whatever";
        DataQuery.LeadsEntity.SaveChanges();

.set(returnType).Add()是否有等效的方法?我不确定是否可以使用变量表和列名进行这种思考:

DataQuery.LeadsEntity.Set(returnType).Add(new returnType { PrimayKeyName = 1, refColumnName = "Something" });

1 个答案:

答案 0 :(得分:1)

如果您不知道先验主键属性的名称是什么,那么从类型中获取它可能会有些痛苦。

This是我发现从实体类型检索主键更可靠的方法:

private string[] GetKeyNames(DbContext context, Type entityType)
{
    ObjectContext objectContext = ((IObjectContextAdapter)context).ObjectContext;
    //create method CreateObjectSet with the generic parameter of the base-type
    MethodInfo method = typeof(ObjectContext).GetMethod("CreateObjectSet", Type.EmptyTypes)
                                             .MakeGenericMethod(entityType);
    dynamic objectSet = method.Invoke(objectContext, null);
    IEnumerable<dynamic> keyMembers = objectSet.EntitySet.ElementType.KeyMembers;
    string[] keyNames = keyMembers.Select(k => (string)k.Name).ToArray();
    _keyNamesCache[entityType] = keyNames;
    return keyNames;
}

但是假设您的主键始终是单个属性,则可以使用反射来创建实体对象并按如下所示设置其属性:

private void CreateEntity(Type entityType, object pkValue, Dictionary<string, object> Columns)
{
    // Create the new entity
    var entity = Activator.CreateInstance(entityType);
    // Get the primary key property name
    var pkName = GetKeyNames(context, entityType).First(); 
    // Set Pk value
    entityType.GetProperty(pkName).SetValue(entity, pkValue);
    // Set other column(s)
    foreach (var col in Columns)
    {
        entityType.GetProperty(col.Key).SetValue(entity, col.Value);
    }
    // Add the entity to the DbSet
    using (var context = new YourContext())
    {
        context.Set(entityType).Add(entity);
    }
}