使用通用插入方法

时间:2017-12-06 20:49:02

标签: c# linq-to-sql entity

我有一种方法可以使用类型T通用地向表插入实体。但我想添加一个功能,以根据匹配器属性(例如Name)检查要添加的实体是否存在于表中。当我执行代码时,它抛出了没有支持到SQL的翻译'在检查线上。我的代码部分如下。我该如何解决这个问题?

    public static InsertStatus Add<T>(T ent, string matcherProp) where T : class
    {
        System.Data.Linq.Table<T> t = otdc.GetTable<T>();

        //Exception on this line
        if (t.Any(item => object.Equals(GetPropValue(item, matcherProp), GetPropValue(ent, matcherProp))))
            return InsertStatus.AlreadyExists;

        try
        {
            t.InsertOnSubmit(ent);
            otdc.SubmitChanges();
            return InsertStatus.Successfull;
        }
        catch
        {
            return InsertStatus.UnknownError;
        }
    }
    public static object GetPropValue(object src, string propName)
    {
        return src.GetType().GetProperty(propName).GetValue(src, null);
    }

2 个答案:

答案 0 :(得分:2)

您需要在运行时创建表达式树。幸运的是,你的情况并非如此;它将类似

var p = Expression.Parameter(typeof(T), "p");
var val = GetPropValue(ent, matcherProp);
var test = Expression.Lambda<Func<T, bool>>(
    Expression.Equal(
        Expression.PropertyOrField(p, matcherProp),
        Expression.Constant(val)
    ), p);

if (t.Any(test))
    return InsertStatus.AlreadyExists;

这样做是为了构建逻辑树:

p => p.{matcherProp} == {val}

其中matcherProp是要测试的成员的名称,val是现有值作为常量。

请注意,如果valnull,您可能会遇到问题,除非您还可以在{{1}上提供属性的类型.PropertyType }}) - 并将其提供给PropertyInfo

编辑:另一种方法是提供Expression.Constant作为常量:

ent

这更类似于:

var p = Expression.Parameter(typeof(T), "p");
var test = Expression.Lambda<Func<T, bool>>(
    Expression.Equal(
        Expression.PropertyOrField(p, matcherProp),
        Expression.PropertyOrField(Expression.Constant(ent), matcherProp),
    ), p);

其中lambda中的p => p.{matcherProp} == ent.{matcherProp} 表现得像一个&#34;捕获的变量&#34;。

答案 1 :(得分:0)

不要将nfdump -r /tmp/nfcapd.201712052349 -o csv > /var/log/netflow/test.csv 设为字符串,而应考虑将其设为matcherProp,以便您可以将其调用为:Expression<Func<T, P>>

然后你需要像

这样的东西
Add(myEntity, e => e.Name)

当然有适当的错误检查。