4

日付情報を含む特定のインターフェイスを実装するX個のエンティティの論理和を使用して、特定の数のOR条件を追加しようとしています。私の問題は、SQLが生成されるときに、すべての論理和条件がQueryOverのルートエンティティを指すことです。

条件を追加するためのジェネリックメソッドを作成しました

    public static QueryOver<T,T2> AddChangedCondition<T,T2>(this QueryOver<T,T2> query, DateTime from, DateTime to, Disjunction disjunction) where T2 : IHaveDate
    {
        if(disjunction == null )
            disjunction = new Disjunction();

        disjunction.Add<T2>(k => (k.DeleteDate > from && k.DeleteDate  < to)
                || k.CreatedDate > from
                || k.UpdatedDate > from);

        return query;
    }

私はそれをこのように使いたい:

Disjunction disjunction = null;
var query = QueryOver.Of<User>()
    .AddChangedCondition(fromDate,toDate, disjunction)
    .JoinQueryOver<Program>(user => user.Programs)
        .AddChangedCondition(fromDate,toDate, disjunction);

query.Where(disjunction);

これから生成されたSQLは、

select ....
from User
where
(
    (
        this_.raderadDatum > @p1 
        and this_.raderadDatum < @p2
    ) 
    or this_.skapadDatum > @p3 
    or this_.uppdateradDatum > @p4
    )
or
    (
        this_.raderadDatum > @p1 
        and this_.raderadDatum < @p2
    ) 
    or this_.skapadDatum > @p3 
    or this_.uppdateradDatum > @p4
    )

エイリアスを使用してさまざまなソリューションを試しましたが、成功しませんでした。どんな助けにも素晴らしいでしょう!

4

3 に答える 3

4

このようにしてみてください、私はいくつかのランダムな条件を挿入し、エイリアスを使用しました

 var qOver = _session.QueryOver<User>(() => usr)         
     .JoinAliases(() => usr.Programs, prg, JoinType.LeftOuterJoin)
     .Where(Restrictions.Or(
                Restrictions.On(() => usr.ID).IsIn(MyValue)
                ,Restrictions.Or(
                   Restrictions.On(() => prg.ID).IsIn(MyValue)
                  , Restrictions.On(() => prg.ID).IsNull)
                 )
               )
     .List<User>();

このようにして、SQLコードは次のようになります

SELECT ....
FROM User
INNER JOIN Program On (...conditions...)
WHERE User.ID = 'MyValue'
OR (Program.ID IN ('Value1','Value2') OR Program.ID IS NULL)

お役に立てば幸いです

于 2011-03-29T14:52:38.217 に答える
4

@Faberが彼の答えで示唆しているように、魔法の文字列を回避することができます。

日付も必要な同様の問題がありました。これが私のコードです:

var disjunction= new Disjunction();

disjunction.Add(Restrictions.On<LocalAsset>(e => e.AvailableFrom).IsBetween(startDate).And(endDate));
disjunction.Add(Restrictions.On<LocalAsset>(e => e.AvailableTo).IsBetween(startDate).And(endDate));

query.Where(disjunction);
于 2012-06-13T13:31:40.563 に答える
0

私はこの解決策を思いつきました(残念ながら、私はマジックストリングを取り除くことができませんでした)

protected Disjunction GetChangedDisjunction<T>(string alias, Disjunction junction = null) where T : IHaveDate
    {
        if(junction == null)
            junction = new Disjunction();

        var toDatum = DateTime.Now;
        junction.Add(Restrictions.And(
                        Expression.Gt(string.Format("{0}.DeletedDate", alias), fromDate), 
                        Expression.Lt(string.Format("{0}.DeletedDate", alias), toDate)));
        junction.Add(Restrictions.Gt(string.Format("{0}.CreatedDate", alias), fromDate));
        junction.Add(Restrictions.Gt(string.Format("{0}.UpdatedDate", alias), fromDate));

        return junction;
    }

そして、私はそれを次のように使用します:

User userAlias= null;
var queryOverUser = QueryOver.Of( () => userAlias);

Program programAlias = null;
queryOverUser 
    .JoinQueryOver(a => a.Programs, () => programAlias, JoinType.LeftOuterJoin)

Disjunction disjunction = new Disjunction();
GetChangedDisjunction<User>("userAlias", disjunction);
GetChangedDisjunction<Program>("programAlias", disjunction);

queryOverUser.Where(disjunction);
于 2011-03-31T13:28:15.253 に答える