我有一种方法可以使用类型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);
}
答案 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
是现有值作为常量。
请注意,如果val
为null
,您可能会遇到问题,除非您还可以在{{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)
当然有适当的错误检查。