我有大约50个数据库,每个数据库有150个表,并且正在使用搜索机制来查询具有特定列的表。大多数数据库结构都是类似的,因此想法是生成EF实体并将接口放在生成的实体后面,如果生成它们的表具有特定的列,那么我以后可以查询该列。
After doing this我试图映射的某些表格列遇到意外问题Long
而其他表格Decimal
(oracle),有时它是Nullable
不是。
我可以看到的一个解决方案是在运行查询之前添加没有任何属性的接口,并在运行时确定该列的特定类型。
有没有办法在接口上为可能有多种类型的属性添加一些类型,因此编译器不会抱怨没有实现?对象不起作用,如果你让我知道需要代码示例,因为问题有些复杂。
我打算在实体上使用的机制:
public static class ExpressionExtensions
{
public static IQueryable<T> ApplySearch<T>(this IQueryable<T> queryable, SearchModel search) where T : class
{
if (search != null && search.PolicyNumber.HasValue && typeof(IPolicyNumber).IsAssignableFrom(queryable.ElementType))
{
queryable = queryable.SearchByPolicyNumber(search);
}
return queryable;
}
public static IQueryable<IPolicyNumber> SearchByPolicyNumber<IPolicyNumber>(this IQueryable<IPolicyNumber> queryable, SearchModel search)
{
var policyNumberParameterLambda = Expression.Parameter((typeof(IPolicyNumber)));
var policyNumberColumnLambda = Expression.Property(policyNumberParameterLambda, "POLICY_NO");
var lambda = Expression.Lambda<Func<IPolicyNumber, bool>>(
Expression.Equal(policyNumberColumnLambda,
Expression.Convert(Expression.Constant(search.PolicyNumber), policyNumberColumnLambda.Type)
), policyNumberParameterLambda);
return queryable.Where(lambda);
}
}
答案 0 :(得分:0)
自己想出来
获取实体的接口必须从此
更改public interface IUniqueId
{
long UNIQUE_ID { get; set; }
}
到这个
public interface IUniqueId<T> : IUniqueId
{
T UNIQUE_ID { get; set; }
}
public interface IUniqueId
{
}
然后将界面放在实体
上来自
public partial class QUOTE_HOUSE : IUniqueId
{
public long UNIQUE_ID { get; set; }
...
}
到
public partial class QUOTE_HOUSE : IUniqueId<long>
{
public long UNIQUE_ID { get; set; }
....
}
和 T4代码 that generates interfaces已从
更改public string EntityClassOpening(EntityType entity)
{
var stringsToMatch = new Dictionary<string,string> { { "POLICY_NO", "IPolicyNumber" }, { "UNIQUE_ID", "IUniqueId" } };
return string.Format(
CultureInfo.InvariantCulture,
"{0} {1}partial class {2}{3}{4}",
Accessibility.ForType(entity),
_code.SpaceAfter(_code.AbstractOption(entity)),
_code.Escape(entity),
_code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)),
stringsToMatch.Any(o => entity.Properties.Any(n => n.Name == o.Key)) ? " : " + string.Join(", ", stringsToMatch.Join(entity.Properties, l => l.Key, r => r.Name, (l,r) => l.Value)) : string.Empty);
}
到
public string EntityClassOpening(EntityType entity)
{
var stringsToMatch = new Dictionary<string,string> { { "POLICY_NO", "IPolicyNumber" }, { "UNIQUE_ID", "IUniqueId" } };
return string.Format(
CultureInfo.InvariantCulture,
"{0} {1}partial class {2}{3}{4}",
Accessibility.ForType(entity),
_code.SpaceAfter(_code.AbstractOption(entity)),
_code.Escape(entity),
_code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)),
stringsToMatch.Any(o => entity.Properties.Any(n => n.Name == o.Key)) ? " : " + string.Join(", ", stringsToMatch.Join(entity.Properties, l => l.Key, r => r.Name, (l,r) => string.Format("{0}<{1}{2}>", l.Value, r.TypeUsage.EdmType.Name, r.Nullable && r.TypeUsage.EdmType.Name!="String" ? "?" : ""))) : string.Empty);
}
Generics FTW确实......
希望这可以节省你一些时间。