# Live Views

## Content

Live views is a powerful feature, so let’s take a little more time to see what live views can do. Live views are designed to make data binding more powerful, so powerful, in fact, that you can develop virtually entire applications with just LINQ (in its LiveLinq form) and data binding.

Live views, called **LiveLinq**, a part of **DataSource for Entity Framework**, is a client-side, in-memory feature applicable not only to Entity Framework and RIA Services data, but to any observable collections in memory, including XML (LINQ to XML object model) and ADO.NET DataSets.

So, for example, you can use live views over Entity Framework data and some other data (for example, XML retrieved from some web service) to integrate that data and to provide easy full-featured data binding to the integrated data. This is a powerful tool for building applications that get data from various sources. For now we’re going to concentrate on how we can use it with the Entity Framework, but if you’d like to explore **LiveLinq** in greater depth, see the [ComponentOne LiveLinq](/componentone/docs/win/online-datasource/ComponentOneLiveLinq) documentation.

In fact, we already saw an example of such customization in [Customizing View](/componentone/docs/win/online-datasource/DesignTimeFeatures/CustomizingView). But there we only changed the properties (fields) of the view and only applied one LINQ operator, **Select**. Let’s apply some more LINQ operators to transform the view. What we do here will be similar to what we did in [Customizing View](/componentone/docs/win/online-datasource/DesignTimeFeatures/CustomizingView), but instead of using [C1DataSource](/componentone/api/win/online-datasource/dotnet-framework-api/C1.Win.Data.Entity.4.8/C1.Win.Data.Entities.C1DataSource.html), we’ll be doing everything in code.

To use live views, follow these steps:

1. Add a new form using the project created to demonstrate [Working with DataSources in Code](/componentone/docs/win/online-datasource/DesignTimeFeatures/WorkingwithDataSourcesinCode2), and add a data grid, **dataGridView1**, to the form.
2. Add the following code to the form class. Here we are following the pattern recommended in [Working with DataSources in Code](/componentone/docs/win/online-datasource/DesignTimeFeatures/WorkingwithDataSourcesinCode2).
<br>
    DOC-DETAILS-TAG-OPEN
    DOC-SUMMARY-TAG-OPEN
    To write code in Visual Basic
    DOC-SUMMARY-TAG-CLOSE

    ```vbnet
    Private _scope As EntityClientScope = Program.ClientCache.CreateScope()
    ```

    DOC-DETAILS-TAG-CLOSE
    DOC-DETAILS-TAG-OPEN
    DOC-SUMMARY-TAG-OPEN
    To write code in C#
    DOC-SUMMARY-TAG-CLOSE

    ```csharp
    private EntityClientScope _scope = Program.ClientCache.CreateScope();
    ```

DOC-DETAILS-TAG-CLOSE

3. Getting *Products* data from the scope, we create a live view and bind the grid to that view in the form’s constructor:
    DOC-DETAILS-TAG-OPEN
    DOC-SUMMARY-TAG-OPEN
    To write code in Visual Basic
    DOC-SUMMARY-TAG-CLOSE

    ```vbnet
    _viewProducts =
                                     (From p In _scope.GetItems(Of Product)()
                                      Where Not p.Discontinued And p.UnitPrice >= 30
                                      Order By p.UnitPrice
                                      Select New With
                                      {
                                          p.ProductID,
                                          p.ProductName,
                                          p.CategoryID,
                                          p.Category.CategoryName,
                                          p.SupplierID,
                                          .Supplier = p.Supplier.CompanyName,
                                          p.UnitPrice,
                                          p.QuantityPerUnit,
                                          p.UnitsInStock,
                                          p.UnitsOnOrder
                                      }).AsDynamic()
                                 dataGridView1.DataSource = _viewProducts
    ```

    DOC-DETAILS-TAG-CLOSE
    DOC-DETAILS-TAG-OPEN
    DOC-SUMMARY-TAG-OPEN
    To write code in C#
    DOC-SUMMARY-TAG-CLOSE

    ```csharp
    _viewProducts =
    (from p in _scope.GetItems<Product>()
                            where !p.Discontinued && p.UnitPrice >= 30
                            orderby p.UnitPrice
                            select new
                            {
                                ProductID = p.ProductID,
                                ProductName = p.ProductName,
                                CategoryID = p.CategoryID,
                                CategoryName = p.Category.CategoryName,
                                SupplierID = p.SupplierID,
                                Supplier = p.Supplier.CompanyName,
                                UnitPrice = p.UnitPrice,
                                QuantityPerUnit = p.QuantityPerUnit,
                                UnitsInStock = p.UnitsInStock,
                                UnitsOnOrder = p.UnitsOnOrder
                            }).AsDynamic();
    dataGridView1.DataSource = _viewProducts;
    ```

    DOC-DETAILS-TAG-CLOSE
<br>
    In this example, we applied several **LiveLinq** operators: *Where*, *OrderBy*, and *Select*. We defined our view as containing products that aren’t discontinued and have a unit price of at least 30, and we sorted our view by unit price.
<br>
    We chose to store the view in a private field **\_viewProducts** here:
<br>
    DOC-DETAILS-TAG-OPEN
    DOC-SUMMARY-TAG-OPEN
    To write code in Visual Basic
    DOC-SUMMARY-TAG-CLOSE

    ```vbnet
    Private _viewProducts As View(Of Object)
    ```

    DOC-DETAILS-TAG-CLOSE
    DOC-DETAILS-TAG-OPEN
    DOC-SUMMARY-TAG-OPEN
    To write code in C#
    DOC-SUMMARY-TAG-CLOSE

    ```csharp
    private View<dynamic> _viewProducts;
    ```

    DOC-DETAILS-TAG-CLOSE
<br>
    That is only because we will need it later. If we did not, we could use a local variable for the view.
<br>
    Syntactically, the query that we wrote for **\_viewProducts** is just standard LINQ. It could be done without [C1DataSource](/componentone/api/win/online-datasource/dotnet-framework-api/C1.Win.Data.Entity.4.8/C1.Win.Data.Entities.C1DataSource.html), with standard LINQ to Objects, and the code would be the same, only instead of **\_scope.GetItems\<Product>()**, you would use something like **ObjectContext.Products**. In fact, we will try to do just that in a moment, once we run the project, to compare what we get from standard LINQ with what we get from **LiveLinq**.
4. Now run the project. You see that the grid shows the filtered set of products, "expensive" products that aren’t discontinued, in the order that we specified with the columns that we specified. Note also that all columns are modifiable, and you can even add and delete rows in the grid. Also note that you can sort the grid at run time by clicking column headers.

To appreciate this full data binding support, compare it with what you would get if you did not use [C1DataSource](/componentone/api/win/online-datasource/dotnet-framework-api/C1.Win.Data.Entity.4.8/C1.Win.Data.Entities.C1DataSource.html), but if you used standard LINQ to Objects instead. It’s easy to compare; just replace **\_scope.GetItems\<Product>()** in the code with **Program.ObjectContext.Products**. Note that you will also need to remove the type **C1.LiveLinq.LiveViews.View** and use the 'var' keyword instead for it to compile, because it will no longer be a live view. The difference is obvious: with standard LINQ, the data in the grid is read-only, and the grid does not support sorting.

But live views offer even more great features. Standard LINQ to Objects produces snapshots of the data that cannot reflect changes in the source data, except some simple property changes, and even then under the strict proviso that you don’t utilize a custom **Select** in your LINQ statement. Live Views, on the other hand, provide dynamic ‘live’ views that automatically reflect changes in their source data. As such, they simplify application development because you can, in most cases, rely on data binding to automate ‘live’ changes in views without the need to synchronize the changes in different parts of the application with code.

To see that the views are indeed ‘live’, open two forms side-by-side. Run your application and open up the Custom Columns form, which we built in [Customizing View](/componentone/docs/win/online-datasource/DesignTimeFeatures/CustomizingView), and the Client Side Querying form, which we just built here. Make some changes to a product in the **CustomColumns** form and observe how they are reflected in the other form. If, for example, you were to increase the **UnitCost** of a product to above **30**, then it would automatically appear in the second form.

To see another example of how live views automatically synchronize themselves with changes in underlying data, follow these steps:

1. Add a live view member of the user control class:
<br>
    DOC-DETAILS-TAG-OPEN
    DOC-SUMMARY-TAG-OPEN
    To write code in Visual Basic
    DOC-SUMMARY-TAG-CLOSE

    ```vbnet
    Private _seafoodProductsView As ClientView(Of Product)
    ```

    DOC-DETAILS-TAG-CLOSE
    DOC-DETAILS-TAG-OPEN
    DOC-SUMMARY-TAG-OPEN
    To write code in C#
    DOC-SUMMARY-TAG-CLOSE

    ```csharp
     private ClientView<Product> _seafoodProductsView;
    ```

DOC-DETAILS-TAG-CLOSE

2. Add the following code to the form’s constructor:
<br>
    DOC-DETAILS-TAG-OPEN
    DOC-SUMMARY-TAG-OPEN
    To write code in Visual Basic
    DOC-SUMMARY-TAG-CLOSE

    ```vbnet
    _seafoodProductsView = _scope.GetItems(Of Product)().AsFiltered(Function(p) p.CategoryID.Value = 8)
    ```

    DOC-DETAILS-TAG-CLOSE
    DOC-DETAILS-TAG-OPEN
    DOC-SUMMARY-TAG-OPEN
    To write code in C#
    DOC-SUMMARY-TAG-CLOSE

    ```csharp
     _seafoodProductsView = _scope.GetItems<Product>().AsFiltered(p => p.CategoryID == 8);
    ```

DOC-DETAILS-TAG-CLOSE

3. Add two buttons, named **btnRaise** and **btnCut**, to the form and add the following handlers to the form’s code :
<br>
    DOC-DETAILS-TAG-OPEN
    DOC-SUMMARY-TAG-OPEN
    To write code in Visual Basic
    DOC-SUMMARY-TAG-CLOSE

    ```vbnet
    Private Sub raiseButton_Click(sender As System.Object, e As System.EventArgs)                                 
        For Each p In _seafoodProductsView                                    
            p.UnitPrice *= 1.2                                 
            Next                             
        End Sub     
    
    Private Sub cutButton_Click(sender As System.Object, e As System.EventArgs)                                 
        For Each p In _seafoodProductsView                                     
            p.UnitPrice /= 1.2                                 
            Next                             
        End Sub
    ```

    DOC-DETAILS-TAG-CLOSE
    DOC-DETAILS-TAG-OPEN
    DOC-SUMMARY-TAG-OPEN
    To write code in C#
    DOC-SUMMARY-TAG-CLOSE
    
       ```csharp
             private void raiseButton_Click(object sender, EventArgs e)
             {
                 foreach (var p in _seafoodProductsView)
                     p.UnitPrice *= 1.2m;
             }
             private void cutButton_Click(object sender, EventArgs e)
             {
                 foreach (var p in _seafoodProductsView)
                     p.UnitPrice /= 1.2m;
             }
       ```
    
    DOC-DETAILS-TAG-CLOSE
4\. Save\, build and run the application\. As you press the buttons\, notice how seafood products appear in the grid because their unit price is now either greater than or equal to **30** or how they disappear when their unit price falls below **30**. All of this happens automatically. You did not have to write any special code to refresh or synchronize the grid.
5\. To see how live views can make almost any GUI\-related code easier to write \(and less error\-prone\)\, let’s add a label that shows the current row count\. Without [C1DataSource](/componentone/api/win/online-datasource/dotnet-framework-api/C1.Win.Data.Entity.4.8/C1.Win.Data.Entities.C1DataSource.html), this would usually be done in a method counting the rows, and that method would have to be called in every place in the code where that count can change. In this example, there would be three such places: on initial load, and in the two methods called when the buttons are pressed, raiseButton\_Click and cutButton\_Click. So it is not very easy to synchronize display with changing data even in this simple example, not to speak of a real application. Live views make all this synchronization code unnecessary. We already saw how it works for a view containing filtering, ordering, and projection (Where, OrderBy, and Select). It works as well for views containing aggregation operations, such as Count. A little difference here is that regular LINQ Count returns a single number, to which you can’t bind a control, so [C1DataSource](/componentone/api/win/online-datasource/dotnet-framework-api/C1.Win.Data.Entity.4.8/C1.Win.Data.Entities.C1DataSource.html) provides a special operation LiveCount that returns a live view instead of a single number, so you can use it in data binding. We can create this binding with a single line of code:

```auto
 labelCount.DataBindings.Add(new Binding("Text",                 
 _viewProducts.LiveCount(), "Value"));
```