rivantsov / vita

VITA Application Framework
MIT License
59 stars 15 forks source link

DBFunction error #223

Closed jasonlaw closed 1 year ago

jasonlaw commented 1 year ago

May I know is the following db function valid? I hit the error when call the function in ScheduleUpdate.

    [SqlExpression(DbServerType.MsSql, "IIF({check}, {trueValue}, {falseValue})")]
    [SqlExpression(DbServerType.MySql, "IF({check}, {trueValue}, {falseValue})")]
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "<Pending>")]
    public static DateTime? DbIIF(this DateTime? dateTime, bool check, DateTime? trueValue, DateTime? falseValue)
    {
        CannotCallDirectly();
        return default;
    }

        var now = MyApp.UtcNow;
        var postQuery = session.EntitySet<ICompanyStats>()
                               .Where(x => x.Id == id)
                               .Select(x => new
                               {
                                   SMS = x.SMS + sms,
                                   Points = x.Points + points,
                                   Vouchers = x.Vouchers + vouchers,
                                   NewMembers = x.NewMembers + newMembers,
                                   Visits = x.Visits + visits,
                                   PointsWithVoucher = x.PointsWithVoucher + pointsWithVoucher,
                                   LastUpdateSMS = x.LastUpdateSMS.DbIIF(sms > 0, now, x.LastUpdateSMS),
                                   //LastUpdatePoints = points > 0 ? now : x.LastUpdatePoints,
                                   //LastUpdateVouchers = vouchers > 0 ? now : x.LastUpdateVouchers,
                                   //LastUpdateNewMembers = newMembers > 0 ? now : x.LastUpdateNewMembers,
                                   //LastUpdateVisits = visits > 0 ? now : x.LastUpdateVisits,
                               });
        session.ScheduleUpdate<ICompanyStats>(postQuery);

Vita.Data.Linq.Translation.LinqTranslationException HResult=0x80131500 Message=Linq to SQL translation failed, invalid expression: Index was outside the bounds of the array. Source=Vita StackTrace: at Vita.Data.Linq.LinqEngine.Translate(LinqCommand command) at Vita.Data.Sql.SqlFactory.GetLinqSql(LinqCommand command) at Vita.Data.Runtime.Database.ExecuteLinqNonQuery(EntitySession session, LinqCommand command, DataConnection conn) at Vita.Data.Runtime.Database.ExecuteScheduledCommands(DataConnection conn, EntitySession session, IList`1 commands) at Vita.Data.Runtime.Database.SaveChangesNoBatch(DbUpdateSet updateSet) at Vita.Data.Runtime.Database.SaveChanges(EntitySession session) at Vita.Data.Runtime.DataSource.SaveChanges(EntitySession session) at Vita.Entities.Runtime.EntitySession.SubmitChanges() at Vita.Entities.Runtime.EntitySession.SaveChanges() at VIQCore.VRewards.ServicesImpl.MemberServiceImpl.RedeemVoucher(String id) in D:\JSL\VIQCore\VRewards.net\VIQCore.VRewards\ServicesImpl\MemberServiceImpl.cs:line 104 at VIQCore.VRewards.API.GraphQL.Mutations.MembershipMutationResolver.RedeemVoucher(IFieldContext context, String id) in D:\JSL\VIQCore\VRewards.net\VIQCore.VRewards.API\GraphQL\Mutations\MemberMutation.cs:line 74 at System.RuntimeMethodHandle.InvokeMethod(Object target, Void* arguments, Signature sig, Boolean isConstructor) at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr args, BindingFlags invokeAttr)

This exception was originally thrown at this call stack: [External Code]

Inner Exception 1: IndexOutOfRangeException: Index was outside the bounds of the array.

jasonlaw commented 1 year ago

I think I found the root cause. The out of bound error is due to the db function arguments (which is 4 in my case) has more than arguments defined in sql expression (which is 3).

image

dbfunc

rivantsov commented 1 year ago

Do not use extension method here (with first 'this' parameter), it definitely does not work; it expects exact match of method parameters with the pattern (param count)

jasonlaw commented 1 year ago

ok clear now, thanks.