0

私はEntityFrameworkを初めて使用し、クエリで使用されるサポートされていない関数の問題に遭遇しました。したがって、コミュニティがエレガントな方法を見つけるのに役立つことを願っています。
クエリは、ユーザー名やWindowsユーザー名に基づいてユーザーを見つけようとします。

[Flags]
public enum IdentifierType
{
    Username = 1,
    Windows = 2,
    Any = Username | Windows,
}

次のコードは、Enum.HasFlagをストア式に変換できないため、 NotSupportedExceptionをスローします。

public User GetUser(IdentifierType type, string identifier, bool loadRelations = false)
{
    using (var context = contextFactory.Invoke())
    {
        var user = context.Users.FirstOrDefault(u => u.Username == identifier && type.HasFlag(IdentifierType.Username)
        || u.WindowsUsername == identifier && type.HasFlag(IdentifierType.Windows));

        return user;
    }
}

クエリを古いファッションの方法で書き直すと、クエリは機能しますが、ブール論理はDBで実行されます。

public User GetUser(IdentifierType type, string identifier, bool loadRelations = false)
{
    using (var context = contextFactory.Invoke())
    {
        var user = context.Users.FirstOrDefault(u => u.Username == identifier && (type & IdentifierType.Username) == IdentifierType.Username
        || u.WindowsUsername == identifier && (type & IdentifierType.Windows) == IdentifierType.Windows);

        return user;
    }
}

WHERE((Username = @username)AND(1 =(3&(1))))OR(WindowsUsername = @windowsusername)AND(2 =(3&(2))))

DBに送信される前にフレームワークにブール論理を評価させて、二項演算がDBレベルで実行されないようにするにはどうすればよいですか?

どんなアイデアでも大歓迎です!

4

3 に答える 3

0

どうぞ(コードをあなたのコードに変換したので、構文的に100%ではないかもしれません)...

public User GetUser(IdentifierType type, string identifier, bool loadRelations = false)
{
    using (var context = contextFactory.Invoke())
    {
        var user = context.Users.FirstOrDefault(u => u.Username == ((type.HasFlag(IdentifierType.Username)) ? identifier : u.Username) && 
    && u.WindowsUsername == ((type.HasFlag(IdentifierType.Username)) ? identifier : u.WindowsUsername);

        return user;
    }
}
于 2013-01-30T14:06:05.147 に答える
0

例えば:

public User GetUser(IdentifierType type, string identifier, bool loadRelations = false)
{
    using (var context = contextFactory.Invoke())
    {
        IdentifierType tw = type & IdentifierType.Windows;
        IdentifierType tu = type & IdentifierType.Username;
        var user = context.Users.FirstOrDefault(u => u.Username == identifier && tu == IdentifierType.Username
        || u.WindowsUsername == identifier && tw == IdentifierType.Windows);

        return user;
    }
}

しかし、データベースサーバーが 1 = (3 & (1)) が定数であることを検出することを願っています

于 2013-01-30T13:37:17.037 に答える
0

申し訳ありませんが、質問が実際の問題を指摘していないことに気付きました。それについてもっと読んだ後、私は質問を書き直さなければなりませんでしたが、最終的に Gert Arnold から素晴らしい回答を得まし

LINQKitはPredicateBuilderのような強力な拡張機能を提供して、OR 条件を使用した動的クエリをカバーします。

于 2013-01-31T10:20:57.763 に答える