2016-06-14 9 views
0

私は約150のテーブルを持ち、特定の列を持つテーブルを照会できる検索メカニズムで動作する約50のデータベースを持っています。ほとんどのデータベース構造は似ていますので、EFエンティティを生成し、生成されるテーブルに特定の列がある場合は生成されたエンティティの背後にインターフェイスを配置して、後でその列を照会することができます。他人にそれはDecimal(オラクル)だと、時にはそれがNullableだと、時々、それはありませんが、私は私がマップしようとしているいくつかのテーブルの列に予期しない問題に遭遇した同じ名前で異なるタイプのプロパティの後ろにインターフェイスを置く

After doing thisLongです。

私が見ることができる1つの解決策は、プロパティを持たずにインターフェイスを追加し、実行時にクエリの実行前にその列の特定の型を決定することです。

プロパティに複数の型がある可能性があるため、コンパイラが実装されていないと不平を言わないように、インターフェイスに型を追加する方法はありますか?オブジェクトが動作しない場合は、質問が多少複雑であるためコード例が必要な場合はお知らせください。私は、エンティティで使用する予定の

メカニズム:

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

ジェネリックスFTW ... – spender

+0

@spenderジェネリックスFTW同志... :) –

答えて

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コード

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); 
} 
から変更
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) => string.Format("{0}<{1}{2}>", l.Value, r.TypeUsage.EdmType.Name, r.Nullable && r.TypeUsage.EdmType.Name!="String" ? "?" : ""))) : string.Empty); 
} 

にジェネリックFTW確かに...

希望、これはあなたにいくつかの時間を節約できます。

関連する問題