SQL 2 LINQ query (called by databinding) completel

2019-06-12 13:59发布

Earlier today I was hunting down a very weird bug... I finally traced it down to what seems to be causing the problem.

The original report can be found here: original question

The details have changed enough to warrant a new question.

It would seem my application sometimes, NOT ALL OF THE TIME, freezes when it reaches the following LINQ query:

using (NetworkDatabaseContext db = new 

NetworkDatabaseContext(UISession.ConnectionString))
{
   Ballast ballast = db.Ballasts.FirstOrDefault(b => b.NetworkId == UISession.NetworkId &&
          b.ShortAddress == this.innerBallast.ShortAddress && b.ControllerSerial == this.controllerSerial);

This is what it looks like:

Not Responding

Most of the time this works just fine... but every now and then it will lock up. This code is part of a BallastListItem class. Items of this class are bound to a ListBox on the Page:

<ListView Name="lstBallasts" Margin="5" DockPanel.Dock="Top" MinHeight="100"><!-- The MinHeight is used to get a good view in the designer -->
        <ListView.View>
            <GridView>
                <GridViewColumn Header="Address" DisplayMemberBinding="{Binding InnerBallast.ShortAddress}" Width="70"/>
                <GridViewColumn Header="Name" Width="300">
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <TextBox Name="txtBallastDisplayName" Text="{Binding DisplayName}" Width="270" MaxWidth="270" MaxLength="100"/>
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
                <GridViewColumn Header="Type" DisplayMemberBinding="{Binding DeviceType}" Width="150"/>
                <GridViewColumn Header="Status" DisplayMemberBinding="{Binding InnerBallast.StandardVersion}" Width="150"/>
            </GridView>
        </ListView.View>
    </ListView> 

The code is part of the DisplayName property getter:

public string DisplayName
    {
        get
        {
            using (NetworkDatabaseContext db = new NetworkDatabaseContext(UISession.ConnectionString))
            {
                Ballast ballast = db.Ballasts.FirstOrDefault(b => b.NetworkId == UISession.NetworkId && 
                   b.ShortAddress == this.innerBallast.ShortAddress && b.ControllerSerial == this.controllerSerial);

So this code is called when databinding occurs, should have realized that before. Still I have no idea why this would sometimes cause problems...

UPDATE

In both cases (when the application freezes and when it does not) the state of the connection is "Closed" just before the query code, as I can see from:

db.Connection.State.ToString()

UPDATE 2 I forgot to mention I moved that code out of the getter, so it is only fetched once. Must have been sleeping while implementing this the first time. The code works fine now, although on XP... every now and then, but much less often the problem still occurs.

* UPDATE 3 * Just to be clear, I'm using an SQL Compact database with very little data

2条回答
对你真心纯属浪费
2楼-- · 2019-06-12 14:24

I agree with Damien, why dont you execute the DB call asynchronously? That way the UI stays responsive and you can handle DB errors in the background gracefully without the user knowing...

查看更多
【Aperson】
3楼-- · 2019-06-12 14:30

Having a property open a database connection and run a query is not a good pattern.

A better approach would be to query a set of objects from LINQ to SQL and bind those to the WPF control instead.

查看更多
登录 后发表回答