具有动态类型的Linq查询

本文关键字:Linq 查询 类型 动态 | 更新日期: 2023-09-27 18:26:33

我使用以下linq来解析我返回的数据集:

 row.Field<long?>("id").HasValue == false &&

我遇到的问题是,当数据集从SqlServer获得时,需要使用<int?>解析字段,而当它从Oracle获得时,则需要将其解析为<long?>。有没有一种方法可以创建一个变量,我可以将其传递给.Field方法来动态设置此数据类型?我想要这样的东西:

Type T = IsSqlServer ? typeof(int?) : typeof(long?);
....
row.Field<T>("id").HasValue == false &&

提前感谢!

具有动态类型的Linq查询

您可以使用反射(不推荐),也可以只使用三元运算符:

!(IsSqlServer ? row.Field<int?>("id").HasValue : row.Field<long?>("id").HasValue)

您可以仅为此目的使用dynamic关键字。请参阅此处以获取编程指南。

我希望这能有所帮助。

这里有一个扩展方法:

public static class DataRowHelpers
{
    private static readonly Dictionary<Type, MethodInfo> FieldSpecialized = new Dictionary<Type, MethodInfo>();
    public static bool FieldHasValue(this DataRow row, Type type, string column)
    {
        MethodInfo fieldSpecialized;
        if(!FieldSpecialized.TryGetValue(type, out fieldSpecialized))
        {       
            var extensions = typeof(DataRowExtensions);
            var fieldGeneric = extensions.GetMethod("Field",
                                                    new[] { typeof(DataRow), typeof(string) });
            fieldSpecialized = fieldGeneric.MakeGenericMethod(type);
            FieldSpecialized.Add(type, fieldSpecialized);
        }

        return fieldSpecialized.Invoke(null, new object[] { row, column }) != null;
    }
}

用法:

var type = IsSqlServer ? typeof(int?) : typeof(long?);
var predicate = row.FieldHasValue(type, "id");