Search

Categories

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Send mail to the author(s) E-mail

# Wednesday, 05 June 2013

When to use CustomUpdate?

  • Useful as don’t need to relaod datasource
  • Will update entity on other screens without having to manually refresh
  • Do not use DbContext.SaveChanges()
  • Need to have Attached code at top of method like Delete in CUD generated

When to use Invoke

  • Doesn’t for simple sections where entity isn’t being displayed on other screens
    • DataSource.Load on callback on UI
    • Force a CacheStop on  LoadingData
  • Have to use DbContext.SaveChanges()

How to Call CustomUpdate vs Invoke

asdf

Differences in Change Tracking with ObjectContext and DbContext

Upgrading to using EF5 requires using the wrapper DbContext instead of ObjectContext in you DomainService class.  One issue I’ve found is have had to add a modified flag to some entities when coming from the UI ie:

[Invoke]
public void ChangePersonAndY(int personID, string roleIDString)
{
    var person = DbContext.People.Where(p => p.PersonId == 2).FirstOrDefault(); // Bill

    string message = "Bill " + DateTime.Now.Millisecond.ToString();
    person.Name = message;

    // Why do I have to add this to make it work? as the Entity was there when it is attached
    DbEntityEntry<Person> entityEntry = this.DbContext.Entry(person);
    entityEntry.State = EntityState.Modified;
            
    // Same as above in 1 line
    //DbContext.Entry(person).State = EntityState.Modified;

    DbContext.SaveChanges();

seems like it doesn’t matter if I come from an Invoke or CustomUpdate or any CRUD.  Don’t need to force a Modified if have attached

| | # 
# Tuesday, 04 June 2013

Create a new Silverlight Business Application

Manage NuGet Packages

  • Add RIA Services for Entity Framework Code-First (DbContext) 10/12/2012 version 4.2.0
  • EntityFramework 5.0.0 (which will overwrite 4.1 which was installed above)

Add ADO.NET Entity Data Model edmx to back end project

image

Compile

Add Domain Service Class to Services folder

<Grid x:Name="LayoutRoot">
        <riaControls:DomainDataSource x:Name="CountriesDataSource" AutoLoad="True" QueryName="GetCountries" LoadSize="20" />
        <ScrollViewer x:Name="PageScrollViewer" Style="{StaticResource PageScrollViewerStyle}">

            <StackPanel x:Name="ContentStackPanel" Style="{StaticResource ContentStackPanelStyle}">

                <TextBlock x:Name="HeaderText" Style="{StaticResource HeaderTextStyle}"
                           Text="{Binding Path=Strings.HomePageTitle, Source={StaticResource ApplicationResources}}"/>
                <sdk:DataGrid Name="ContactsGrid" ItemsSource="{Binding Data, ElementName=CountriesDataSource}" />
            </StackPanel>

        </ScrollViewer>
    </Grid>

Add this to Home.xaml using Drag n Drop to easily get the references right

public Home()
        {
            InitializeComponent();

            this.Title = ApplicationStrings.HomePageTitle;
            var context = new DomainService1();
            CountriesDataSource.DomainContext = context;
        }

Code behind wire up a context

Web.config

Should look like this:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <sectionGroup name="system.serviceModel">
      <section name="domainServices" type="System.ServiceModel.DomainServices.Hosting.DomainServicesSection, System.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" allowDefinition="MachineToApplication" requirePermission="false" />
    </sectionGroup>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <system.web>
    <httpModules>
      <add name="DomainServiceModule" type="System.ServiceModel.DomainServices.Hosting.DomainServiceHttpModule, System.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    </httpModules>
    <compilation debug="true" targetFramework="4.5">
      <assemblies>
        <add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
      </assemblies>
    </compilation>
    <globalization culture="auto" uiCulture="auto" />
    <authentication mode="Forms">
      <forms name=".BusinessApplication6_ASPXAUTH" timeout="2880" />
    </authentication>
    <roleManager enabled="true" defaultProvider="DefaultRoleProvider">
      <providers>
        <clear />
        <add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />
        <add name="DefaultRoleProvider" type="System.Web.Providers.DefaultRoleProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />
      </providers>
    </roleManager>
    <profile defaultProvider="DefaultProfileProvider">
      <properties>
        <add name="FriendlyName" />
      </properties>
      <providers>
        <add name="DefaultProfileProvider" type="System.Web.Providers.DefaultProfileProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />
      </providers>
    </profile>
    <membership defaultProvider="DefaultMembershipProvider">
      <providers>
        <add name="DefaultMembershipProvider" type="System.Web.Providers.DefaultMembershipProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
      </providers>
    </membership>
    <!--
            If you are deploying to a cloud environment that has multiple web server instances,
            you should change session state mode from "InProc" to "Custom". In addition,
            change the connection string named "DefaultConnection" to connect to an instance
            of SQL Server (including SQL Azure and SQL  Compact) instead of to SQL Server Express.
      -->
    <sessionState mode="InProc" customProvider="DefaultSessionProvider">
      <providers>
        <add name="DefaultSessionProvider" type="System.Web.Providers.DefaultSessionStateProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" />
      </providers>
    </sessionState>
  </system.web>
  <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <modules runAllManagedModulesForAllRequests="true">
      <add name="DomainServiceModule" preCondition="managedHandler" type="System.ServiceModel.DomainServices.Hosting.DomainServiceHttpModule, System.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    </modules>
  </system.webServer>
  <system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <connectionStrings>
    <add name="DefaultConnection" connectionString="Data Source=(LocalDB)\v11.0;Initial Catalog=aspnet-BusinessApplication6.Web-20130604101429;Integrated Security=True" providerName="System.Data.SqlClient" />
    <add name="TestDBEntities" connectionString="metadata=res://*/Model.csdl|res://*/Model.ssdl|res://*/Model.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=.\SQLEXPRESS;initial catalog=TestDB;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
  </connectionStrings>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
  </entityFramework>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="EntityFramework" publicKeyToken="b77a5c561934e089" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>
| | # 

http://mcasamento.blogspot.co.uk/2012/10/entity-framework-5-code-first-and-wcf.html includes the demo EFCodeFirst_WCFRiaDemo_2012-10-28 which uses the CodeDom generator…as opposed to the T4 based code generator.  Has domain model classes in another assembly.

Although couldn’t get Enable-Migrations –EnableAutomaticMigrations to work.

  • Codefirst
  • Domain Service classes in another assebmly
<configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>

and the binding redirect which is used to make everything work:

<runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="EntityFramework" publicKeyToken="b77a5c561934e089" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>

RIA Books

http://jeffhandley.com/archive/2012/12/10/RIA-Services-NuGet-Package-Updates-ndash-Including-Support-for-EntityFramework.aspx  RIA Services NuGet Package including support for EF5.. including all EF versions >= 4.1

https://github.com/jeffhandley/riabooks#readme

This is EF5 and RIA Services for EF Code-First (DbContext) installed.

  • EF5
  • DbContext NuGet installed
  • 2 projects only

update-database –Verbose getting an error

System.Data.SqlClient.SqlException (0x80131904): Cannot attach the file 'C:\Users\davidma\Downloads\RIABooks-master\RIABooks-master\RIABooks.Web\App_Data\RIABooks.Web.Models.BookModel.mdf' as database 'RIABooks.Web.Models.BookModel'.

image

“RIAServices.EntityFramework provides the DbDomainService<T> class which can be used to create Domain Service classes for use with a DbContext from the EntityFramework package.  This package supports versions of EntityFramework starting with EF 4.1, including EntityFramework 5.0.0.”

image
EntityFramework is 5.0.0.0

Microsoft.ServiceModel.DomainServices.EntityFramework is 4.0.0.0

The Old Wizard Way - EF4

The out of the box Silverlight Business Application uses ObjectContext.  However it can still use the same EF5 DLL (which includes EF4)

image

This adds in EF4 automatically into references (although in VS2012 uses the EF5 dll)

then change code gen strategy from none to default (and delete the 2 T4 template code genned files)

image
Then can access from the front end like this: Use drag and drop to easily add in DomainDataSource, and DataGrid

Wizard generates DomainService1.cs and DomainService1.metadata.cs

using BusinessApplication2.Web;
    using System.Data;
    using System.Linq;
    using System.ServiceModel.DomainServices.EntityFramework;
    using System.ServiceModel.DomainServices.Hosting;


    // Implements application logic using the TestDBEntities1 context.
    // TODO: Add your application logic to these methods or in additional methods.
    // TODO: Wire up authentication (Windows/ASP.NET Forms) and uncomment the following to disable anonymous access
    // Also consider adding roles to restrict access as appropriate.
    // [RequiresAuthentication]
    [EnableClientAccess()]
    public class DomainService1 : LinqToEntitiesDomainService<TestDBEntities1>
    {

        // TODO:
        // Consider constraining the results of your query method.  If you need additional input you can
        // add parameters to this method or create additional query methods with different names.
        // To support paging you will need to add ordering to the 'Countries' query.
        public IQueryable<Country> GetCountries()
        {
            return this.ObjectContext.Countries;
        }
So EF was in System.ServiceModel.DomainServices.EntityFramework which is version 4.0.0.0, which is in:

C:\Program Files (x86)\Microsoft SDKs\RIA Services\v1.0\Libraries\Server\System.ServiceModel.DomainServices.EntityFramework.dll

 

public Home()
        {
            InitializeComponent();

            this.Title = ApplicationStrings.HomePageTitle;

            var context = new DomainService1();
            CountriesDataSource.DomainContext = context;
        }

Wiring up context
<Grid x:Name="LayoutRoot">
        <riaControls:DomainDataSource x:Name="CountriesDataSource" AutoLoad="True" QueryName="GetCountries" LoadSize="20" />
        <ScrollViewer x:Name="PageScrollViewer" Style="{StaticResource PageScrollViewerStyle}">

            <StackPanel x:Name="ContentStackPanel" Style="{StaticResource ContentStackPanelStyle}">

                <TextBlock x:Name="HeaderText" Style="{StaticResource HeaderTextStyle}"
                           Text="{Binding Path=Strings.HomePageTitle, Source={StaticResource ApplicationResources}}"/>

                <sdk:DataGrid Name="ContactsGrid" ItemsSource="{Binding Data, ElementName=CountriesDataSource}" />
            </StackPanel>
          
        </ScrollViewer>
    </Grid>

image

Using Silverlight Business Application and EF5

Create a new Silverlight Business Application

image
Add in NuGetpackage – RIAServices.EntityFramework package 4.2.0

Added

  • EntityFramework (5.0.0.0)
  • Microsoft.ServiceModel.DomainServices.EntityFramework (4.0.0.0) – DbDomainService<T> in here
  • System.Data.Entity (4.0.0.0)

as opposed to old way of:

  • EntityFramework (5.0.0.0)
  • System.Data.Entity (4.0.0.0)
  • System.ServiceModel.DomainServices.EntityFramework (4.0.0.0) – LinqToEntitiesDomainService<T> in here

Enables us to create a DomainService class based of EF Code First DbContext classes

image

Now, want to create our DomainService – used Wizard which worked.

image
Success (although am not sure) – SL5, WCF RIA Services, and EF5 getting data.

  <connectionStrings>
    <add name="DefaultConnection" connectionString="Data Source=(LocalDB)\v11.0;Initial Catalog=aspnet-BusinessApplication3.Web-20130603105310;Integrated Security=True" providerName="System.Data.SqlClient" />
    <add name="TestDBEntities" connectionString="metadata=res://*/Services.Model1.csdl|res://*/Services.Model1.ssdl|res://*/Services.Model1.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=.\SQLEXPRESS;initial catalog=TestDB;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
  </connectionStrings>

  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="EntityFramework" publicKeyToken="b77a5c561934e089" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

Added in this at end of web.config..but didn’t work.  Still not sure if am actually using EF5!

How to Really Use EF5

Above when you put in the NuGet package of RiaServices, it actually puts in EF4.2.  So you have to put in EF5 manually then make sure the web.config looks like this:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <sectionGroup name="system.serviceModel">
      <section name="domainServices" type="System.ServiceModel.DomainServices.Hosting.DomainServicesSection, System.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" allowDefinition="MachineToApplication" requirePermission="false" />
    </sectionGroup>
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />

  <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --></configSections>
  
  <system.web>
    <httpModules>
      <add name="DomainServiceModule" type="System.ServiceModel.DomainServices.Hosting.DomainServiceHttpModule, System.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    </httpModules>
    <compilation debug="true" targetFramework="4.5">
      <!--<assemblies>
        <add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
      </assemblies>-->
    </compilation>

    <globalization culture="auto" uiCulture="auto" />
    
    <authentication mode="Forms">
      <forms name=".BusinessApplication5_ASPXAUTH" timeout="2880" />
    </authentication>
    <roleManager enabled="true" defaultProvider="DefaultRoleProvider">
      <providers>
        <clear />
        <add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />
        <add name="DefaultRoleProvider" type="System.Web.Providers.DefaultRoleProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />
      </providers>
    </roleManager>
    <profile defaultProvider="DefaultProfileProvider">
      <properties>
        <add name="FriendlyName" />
      </properties>
      <providers>
        <add name="DefaultProfileProvider" type="System.Web.Providers.DefaultProfileProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />
      </providers>
    </profile>
    <membership defaultProvider="DefaultMembershipProvider">
      <providers>
        <add name="DefaultMembershipProvider" type="System.Web.Providers.DefaultMembershipProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
      </providers>
    </membership>

    <sessionState mode="InProc" customProvider="DefaultSessionProvider">
      <providers>
        <add name="DefaultSessionProvider" type="System.Web.Providers.DefaultSessionStateProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" />
      </providers>
    </sessionState>
    <!-- here -->
  </system.web>
  
  <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <modules runAllManagedModulesForAllRequests="true">
      <add name="DomainServiceModule" preCondition="managedHandler" type="System.ServiceModel.DomainServices.Hosting.DomainServiceHttpModule, System.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    </modules>
  </system.webServer>
  <system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  
  <connectionStrings>
    <add name="DefaultConnection" connectionString="Data Source=(LocalDB)\v11.0;Initial Catalog=aspnet-BusinessApplication5.Web-20130603151851;Integrated Security=True" providerName="System.Data.SqlClient" />
    <add name="TestDBEntities" connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=.\SQLEXPRESS;initial catalog=TestDB;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
  </connectionStrings>

  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="v11.0" />
      </parameters>
    </defaultConnectionFactory>
  </entityFramework>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="EntityFramework" publicKeyToken="b77a5c561934e089" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
  
</configuration>

http://social.msdn.microsoft.com/Forums/en-US/silverlightwcf/thread/c053a433-7e33-46d1-827b-0976fab255f1

| | # 
# Tuesday, 12 February 2013

The data transfer for WCF RIA Services is actually done in a binary format, which does not make it particularly easy when trying to see what’s coming down the wire.

Meet the WCF Binary inspector for Fiddler
http://archive.msdn.microsoft.com/wcfbinaryinspector

The installation process nothing more than dropping a “dll” into your “\\Program Files x86\Fiddler2\Inspectors” folder

image

Thanks to Jau for this!

| | # 
# Monday, 21 January 2013

Made a test app before upgrading production app:

Silverlight Business app.  EF5 (nuget) Default generation, then added a domain service.  Compiled.  Then added in a ref to System.Windows.Controls.Data on the front end project.

public Home()
        {
            InitializeComponent();

            this.Title = ApplicationStrings.HomePageTitle;

            var context = new AdventureDomainContext();
            ContactsDataSource.DomainContext = context;

        }

and front end XAML

   xmlns:riaControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.DomainServices"
                 
mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480"  
Style="{StaticResource PageStyle}">
    

    <Grid x:Name="LayoutRoot">
        <riaControls:DomainDataSource x:Name="ContactsDataSource" AutoLoad="True" QueryName="GetContacts" LoadSize="20" />

        <ScrollViewer x:Name="PageScrollViewer" Style="{StaticResource PageScrollViewerStyle}">

            <StackPanel x:Name="ContentStackPanel" Style="{StaticResource ContentStackPanelStyle}">

                <TextBlock x:Name="HeaderText" Style="{StaticResource HeaderTextStyle}" Text="{Binding Path=Strings.HomePageTitle, Source={StaticResource ApplicationResources}}"/>

                <sdk:DataGrid Name="ContactsGrid" ItemsSource="{Binding Data, ElementName=ContactsDataSource}" />

            </StackPanel>

        </ScrollViewer>
    </Grid>

To give:

image

contact and contacttype

To upgrade to EF5 we need to wire up like CodeFirst – which means changing the domain service.

http://jeffhandley.com/archive/2012/12/10/RIA-Services-NuGet-Package-Updates-ndash-Including-Support-for-EntityFramework.aspx

http://varunpuranik.wordpress.com/2011/06/29/wcf-ria-services-support-for-ef-4-1-and-ef-code-first/

Good example here: https://github.com/jeffhandley/riabooks#readme

and discussions here: http://social.msdn.microsoft.com/Forums/en-US/silverlightwcf/thread/f12c6d40-5462-4ef4-9f71-b9ed41247cb1

which include putting models in separate solutions.

| | # 
# Thursday, 10 January 2013

Eventvwr

1
Useful when debugging the WCF service. 

Run tests against service methods.

Useful when issue with edmx or something on the backend, and the wcf service doesn’t surface the error to the ui.

Run as non debug

Popup window can give better errors compared with debugger

Run Service directly in the Browser

image

Catching Debugging errors in VS2012

http://www.scottleckie.com/2010/04/code-4004-unhandled-error-in-silverlight-application/
I have plugged into app.xaml:

private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
        {
            // If the app is running outside of the debugger then report the exception using a ChildWindow control.
            if (!System.Diagnostics.Debugger.IsAttached)
            {
                // NOTE: This will allow the application to continue running after an exception has been thrown but not handled.
                // For production applications this error handling should be replaced with something that will report the error to the website and stop the application.
                e.Handled = true;
                ErrorWindow.CreateNew(e.ExceptionObject);
            }
            else
            // Even in debugger catch errors as sometimes badly managed
            // http://www.scottleckie.com/2010/04/code-4004-unhandled-error-in-silverlight-application/
            {
                e.Handled = true;
                ErrorWindow.CreateNew(e.ExceptionObject);
                //System.Diagnostics.Debug.WriteLine(e.ExceptionObject.ToString());
            }
        }

Fiddler

asdf

Include Service exception details:

http://social.msdn.microsoft.com/Forums/en/windowsazuretroubleshooting/thread/e26aaa88-672c-4888-b54d-6c29bb0329f4

| | # 
# Wednesday, 12 December 2012

Getting RIA to have an overall context..

wiring up a global context… easier in codebehind.

http://stackoverflow.com/questions/2996686/using-ria-services-filterdescriptor-from-code-behind

Example of setting many properties in codebehind:

//public DomainDataSource accountsDataSourceT32;
            if (ddsSetup == false)
            {
                //accountsDataSourceT32 = new DomainDataSource();
                //accountsDataSourceT32.AutoLoad = true;
                //accountsDataSourceT32.QueryName = "xxxx";
                //accountsDataSourceT32.LoadSize = 30;
                //accountsDataSourceT32.PageSize = 30;
                AccountsDataSourceT32.DomainContext = uerDomainContext;

                //var p = new Parameter();
                //p.ParameterName = "xxLogin";
                //p.Value = ADLogin;

                //var p3 = new Parameter();
                //p3.ParameterName = "xxRID";
                //p3.Value = "AllUsers";

                //var pp = new Parameter();
                //pp.ParameterName = "xxAID";
                //pp.Value = "0";

                //accountsDataSourceT32.QueryParameters.Add(p);
                //accountsDataSourceT32.QueryParameters.Add(pp);
                //accountsDataSourceT32.QueryParameters.Add(p3);

                //accountsDataSourceT32.SortDescriptors.Add(new SortDescriptor("LastName", ListSortDirection.Ascending));

                //TextBlock txtFilterName = new TextBlock();
                //txtFilterName.Text = "xxx";

                //var f = new FilterDescriptor();
                //f.PropertyPath = "LastName";
                //f.Operator = FilterOperator.Contains;
                ////f.Operator = FilterOperator.IsEqualTo;
                ////f.Value = "xxxt";

                //Binding b = new Binding("Text") { ElementName = "TextBoxAccountSearchT32" };
                //BindingOperations.SetBinding(f, FilterDescriptor.ValueProperty, b);
                //accountsDataSourceT32.FilterDescriptors.Add(f);


                AccountsDataSourceT32.Load();
                ddsSetup = true;

                //this.Resources.Add("accountsDataSourceT32", accountsDataSourceT32);

                AccountItemsT32.ItemsSource = AccountsDataSourceT32.Data;
            }

However am finding the clearest way is to set in XAML everything except for the domaincontext.

| | # 
# Monday, 19 November 2012

http://technet.microsoft.com/cs-cz/sysinternals/bb963907

http://msdn.microsoft.com/en-us/library/ee707353%28VS.91%29.aspx

Querying the AD using an explorer.

image

Make sure NTLM is running.

HTTPS


        EnableClientAccess(RequiresSecureEndpoint=true)... needs https.

| | # 
# Thursday, 15 November 2012

I’m trying to do something like RemoveAccountFromRole

Can do it with an Invoke method call on RIA, however it doesn’t refresh the data on the front end:

Although the Invoke attribute is optional, to be considered an invoke method a
method shouldn’t take entities as a parameter or return an entity, IEnumerable, or
IQueryable of entities as a result.

Conventions

Get, Insert, Update, Delete

Testing a domainservice:

https://msdnrss.thecoderblogs.com/2011/08/unit-testing-a-wcf-ria-domainservice-part-3-the-domainservicetesthost/

Getting the correct context to work on so INotifyPropertyChanged works.

Update a single entity

Update Multiple

Forcing a Rebind

couldn’t get this to work..

            // Force rebind - doesn't work             //BindingExpression bindExp = AccountItemsT32.GetBindingExpression(ListBox.ItemsSourceProperty);             //Binding bind = bindExp.ParentBinding;             //AccountItemsT32.SetBinding(ListBox.ItemsSourceProperty, bind);             //AccountItemsT32.GetBindingExpression(ListBox.ItemsSourceProperty).UpdateSource();
 

Eager Loading

http://blogs.msdn.com/b/alexj/archive/2009/06/02/tip-22-how-to-make-include-really-include.aspx – workaround for joins and includes

Reload DomainContext

http://stackoverflow.com/questions/3899721/silverlight-4-ria-update-item-in-domaindatasource-only-updates-after-refresh

| | # 
# Saturday, 20 October 2012
  • Auto creation of CRUD methods for entities
  • Auto generation and sync of service methods and their client side proxies
  • Validation rules / arbitrary business logic methods that are shared
  • ASP.NET Security

image
UI Tooltips, validation requires no trip to server.  Child window spins round from login.

image
Default membership provider uses a db for developers as default.

image

Text values help in ApplicationStrings resource file

image
Wiring it up

Exposing Data with the Domain Service

AdventureWorksEntities.edmx

image
The template creates the INCORRECT edmx file for RIA

image
Correct – default code gen strategy

image
Top level Visual C# already installed

image

2 classes created in the services folder:

  • EmployeeServics.
  • EmployeeService.metadata.cs

Conventions

Query

LINQ to Entities and EF

image

Query methods fall into three primary buckets:
■ Methods returning a single concrete instance of an entity
■ Methods returning a collection or enumerable of zero or more entities
■ Methods returning an IQueryable of the entity

Composed Queries

Can have the Grid bound to GetSalariedEmployees then it can do sorting/paging/filtering on that query.. but all done on the SQL Server

PreSorted data on server:

public IQueryable<Employee> GetEmployeesSorted()
{
return from Employee emp in ObjectContext.Employees
orderby emp.Title, emp.HireDate
select emp;
}


and use it like this on the client:
EmployeeContext context = new EmployeeContext();
EntityQuery<Employee> query =
from emp in context.GetEmployeesSortedQuery()
where emp.SalariedFlag == true
select emp;

2 steps happen together on the server.

Insert, Update, and Delete Methods

update, coppies…

Invoke

Perform a calculation or return a piece of data eg CalculateVacationBonus which returns an int.

Used where we don’t need:

  • Change tracking
  • Deferred execution

Shouldn’t be used to load data

Using Domain Service from Silverlight

  • Connect via code
  • Connect via XAML (easiest)

image

image

image

image
This client side LINQ will be executed on the SQL Server.

DomainDataSource Control

image
No code in code behind.  Had to add a reference to System.Windows.Controls.DomainServices

Filtering, Sorting, Grouping and Paging

One of the most compelling reasons to use DomainDataSource!

image
Filters on each letter pressed

FilterDescriptors – in our case we are using Contains.  Can use this descriptors to create any query

Sorting

image

<riaControls:DomainDataSource.SortDescriptors>
<riaControls:SortDescriptor Direction="Ascending"
PropertyPath="Title" />
<riaControls:SortDescriptor Direction="Ascending"
PropertyPath="HireDate" />
</riaControls:DomainDataSource.SortDescriptors>

Note how the grid knows what has been sorted (arrows) by default.

image
Sorting was done on the SQL Server.

Grouping

<riaControls:DomainDataSource.GroupDescriptors>
<riaControls:GroupDescriptor PropertyPath="Title" />
</riaControls:DomainDataSource.GroupDescriptors>

image

Paging

  • Preload everything and allow scrolling
  • Infinite scroll that performs lazy fetching
  • Data paging

 

  • PageSize 15
  • LoadSize 30
  • DataPager control

this would make every other page hit the database

image

 

Updating Data

Using the DataForm UI

image

<sdk:DataGrid x:Name="EmployeeGrid" ItemsSource="{Binding Data, ElementName=DataSource}" Grid.Column="0" Margin="5,38,5,5" />

            <dataForm:DataForm Grid.Column="1" Margin="5 40 0 40"
                ItemsSource="{Binding Data, ElementName=DataSource}"
                CurrentItem="{Binding SelectedItem,ElementName=EmployeeGrid, Mode=TwoWay}" />

Note how binding it TwoWay for current navigation so can use either view to navigate through data.

image
Save changes button.  It is greyed out until there are actual changes which means you have to click to anothe box before you can click on Submit

<Button x:Name="SubmitChanges"
                Grid.Column="1" Margin="5"
                HorizontalAlignment="Right"
                VerticalAlignment="Top"
                Height="25" Width="120"
                Command="{Binding SubmitChangesCommand, ElementName=DataSource}"
                Content="Submit Changes" />

Calling an Invoke Operation from the Client

asd

image
Calling ‘server side’ logic to calculate the vacation bonus.

image
Server side logic in EmloyeeService.  Notice the method takes only 1 paramter, but we’re calling it with 3 above – a callback and a Data.  The Data in this case is an Employee, which we need to use in the callback to update the object (VacationHours)

The entity is then marked as HasChanges=true, so then it is eligible for SubmitChanges call ie Submit button goes ungrey.

ToolTips and Validation

image
Tooltip on BirthDate now works

image
Editing the server side EmployeeService.metadata.cs

image

image
EmployeeService.metadata.cs, Employee, EmployeeMetaData nested class

| | #