4

linqで文字列をintに変換してエンティティに変換しますが、Convert.ToInt32とint.Parseはsqlに変換できません。データベースは大きく、すべてをメモリに取得できません(60kレコードを超えて大きくなります)。クエリは次のようになります。

int myNumber = 1390;
var result = from dr in myEntitiy.TableX
             where (Convert.ToInt32(dr.stringYear) > myNumber) // <== error
             select dr; 

エラーは、変換メソッドを変換できないと言います

LINQ to Entitiesは、メソッド'Int32 ToInt32(System.String)'メソッドを認識せず、このメソッドをストア式に変換できません。

何の解決策

更新:これを行う方法がない場合は、これについて確認してください。データベースのフィールドタイプを変更する必要がありますが、難しいでしょう:(

4

2 に答える 2

4

1000年未満または9999年を超えない限り、文字列として比較を行うのは非常に安全だと思います。

... dr.stringYear.CompareTo(myNumberString) > 0

EFはこれを次のようなSQL述語に変換します

WHERE [alias].[stringYear] > @p

これはSQLでは可能ですが、C#では不可能です。

利点は、上の任意のインデックスをstringYear実行プランで使用できることです。数値に変換stringYearすると、インデックスが削除されます。

このメソッドは、文字列列にギザギザの文字列値が含まれている場合でも役立ちます。このような場合、述語は長さと組み合わせる必要があります。たとえば、整数としての数値文字列が参照値より大きいすべてのエンティティを検索するには

var len = myNumberString.Lenght;

var query = 
    from row in context.LegacyTable
    where row.NumericString.CompareTo(myNumberString) > 0
       && row.NumericString.Length >= len
    select row; 

その場合、クエリエンジンは長さの比較にインデックスを使用できませんが、比較には使用できる可能性があります>

于 2012-05-09T17:59:53.893 に答える
2

これは機能しますが、生成されたSQLは乱雑になります

int myNumber = 1390;
var result = from dr in myEntitiy.TableX
             let num = myEntitiy.TableX.Take(1).Select(x => dr.stringYear).Cast<int>().FirstOrDefault()
             where num > myNumber
             select dr; 
于 2012-05-09T17:25:31.083 に答える