3

I am not sure what is wrong with my code can someone help fix the error? The error is in the timer.Tick() line. It's supposed to make a stopwatch.

namespace App3
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {                
            this.InitializeComponent();
        }
        private int myCount;

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            DispatcherTimer timer = new DispatcherTimer();
            timer.Tick += new EventHandler<object>(timer_Tick);
            timer.Interval = TimeSpan.FromSeconds(5);
            timer.Start();    
        }


        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            base.OnNavigatedFrom(e);
        }

        private void timer_Tick(object sender, EventArgs e)
        {
            myCount++;
            Label.Text = myCount.ToString();
        }
    }

The MSDN documentation states that SCOPE_IDENTITY:

"retrieves the last identity values that are generated in any table in the current session"

Looking at the Massive source code, it appears that every call to Scalar() opens a new connection:

/// <summary>
/// Returns a single result
/// </summary>
public virtual object Scalar(string sql, params object[] args) {
    object result = null;
    using (var conn = OpenConnection()) {            // <-- see this ...
        result = CreateCommand(sql, conn, args).ExecuteScalar();
    }
    return result;
}

...

/// <summary>
/// Returns and OpenConnection
/// </summary>
public virtual DbConnection OpenConnection() {
    var result = _factory.CreateConnection();
    result.ConnectionString = ConnectionString;
    result.Open();                                  // <-- ...and this 
    return result;
}

Therefore, every time you are doing table.Scalar("select scope_identity()"); you are actually doing this in a new connection (which means a different session/scope).

This explains the DBNull result.

But since you are already doing:

var newID = table.Insert(...)

you might want to inspect the value of newID after the insert happens; I hope you'll find something nice in there.

At least, that's what the code for Insert() leads me to believe:

   public virtual dynamic Insert(object o) {
        var ex = o.ToExpando();
        if (!IsValid(ex)) {
            throw new InvalidOperationException("Can't insert: " + String.Join("; ", Errors.ToArray()));
        }
        if (BeforeSave(ex)) {
            using (dynamic conn = OpenConnection()) {
                var cmd = CreateInsertCommand(ex);
                cmd.Connection = conn;
                cmd.ExecuteNonQuery();
                cmd.CommandText = "SELECT @@IDENTITY as newID";
                ex.ID = cmd.ExecuteScalar();
                Inserted(ex);
            }
            return ex;
        } else {
            return null;
        }
    }
4

4 回答 4

5

DispatcherTimer.Tick is an EventHandler, not an EventHandler<object>.

You need to change your code to specify this correctly:

 timer.Tick += new EventHandler(timer_Tick);

Note that this can also be written in short form, which is typically safer:

timer.Tick += timer_Tick;
于 2013-02-25T20:44:15.110 回答
4

Delegate types are not required when attaching events, the compiler can figure it out for you. Try this instead:

timer.Tick += timer_Tick;

As for why you get the error currently, the EventHandler delegate is declared like this:

public delegate void EventHandler<TEventArgs>(
    Object sender,
    TEventArgs e
)

This means the type you put in the brackets represents the second argument in the function.

So when you type EventHandler<object>, the compiler looks for a function like timer_Tick(Object sender, object e) which it does not find, hence the error. To use the full delegate type, it would have to be EventHandler<EventArgs>

于 2013-02-25T20:44:39.163 回答
1

我通过两个小改动解决了同样的问题:

1)将第二个参数更改为对象类型:

取而代之的是:

private void timer_Tick(object sender, EventArgs e)

用这个:

private void timer_Tick(object sender, **object** e)

2) 简化

取而代之的是:

timer.Tick += new EventHandler<object>(timer_Tick);

用这个:

timer.Tick += timer_Tick;  // as suggested by WildCrustacean above
于 2013-12-30T04:31:48.883 回答
1

而不是新的EventHandler<object>,做new EventHandler。或者只是把+= timer_Tick;.

于 2013-02-25T20:45:03.673 回答