Search

Categories

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Send mail to the author(s) E-mail

# Tuesday, 21 January 2014

EF not using [DefaultValue] attribute.

http://stackoverflow.com/questions/11546295/entity-framework-migrations-dont-include-defaultvalue-data-annotation-ef5rc/13953246#13953246

    public ActionResult Create()
    {
        ViewBag.StoryTypeID = new SelectList(db.Query<StoryType>(), "StoryTypeID", "Name");

        // Passing a new Story so get default rating set as 1
        return View(new Story {Rating = 1});
    }
| | # 
# Monday, 02 December 2013

Standard:

string connectionString = ConfigurationManager.ConnectionStrings["DaveConnection"].ConnectionString;

//var connectionString = @"server=.\SQLEXPRESS;database=TestDB;Trusted_Connection=True;";

using (var connection = new SqlConnection(connectionString))
{
    connection.Open();
    using (var command = new SqlCommand("SELECT Name FROM Countries", connection))
    {
        using (var reader = command.ExecuteReader())
        {
            while (reader.Read())
            {
                var text = reader["Name"];
                //var text = reader[0];
                //var text = reader.GetString(reader.GetOrdinal("Name"));
                //TextBox1.Text += reader.GetString(0) + ", ";
                TextBox1.Text += text + ", ";
            }
        }
    }
}
<configuration>
    <system.web>
      <compilation debug="true" targetFramework="4.5" />
      <httpRuntime targetFramework="4.5" />
    </system.web>

  <connectionStrings>
    <add name="DaveConnection" connectionString="Data Source=.\SQLEXPRESS;database=TestDB;Trusted_Connection=True" providerName="System.Data.SqlClient" />
  </connectionStrings>


</configuration>

Simplest thing to do was to get EF to pass the connection string:

            // Gets the DbContext's connection string
            var conn = (SqlConnection)DbContext.Database.Connection;

EF4 and above:

var results = context.Database.SqlQuery<QueryAResult>(sql);

var dtoList = new List<AccountsByUserDTO>();

foreach (var x in results)
{
    var dto = new AccountsByUserDTO { AccountID = x.AccountID, Name = x.Name + " (" + x.Platform + ")" };
    dtoList.Add(dto);
}
class QueryAResult
{
    public long AccountID { get; set; }
    public string Name { get; set; }
    public string Platform { get; set; }
}

This is brittle, but does work.  I used a nested class just above the data access method so as to keep everthing on 1 page.

Also possible to query SP’s easily this way.

DataTable and DataAdapter

// Gets the DbContext's connection string
var conn = (SqlConnection)DbContext.Database.Connection;

if (conn != null && conn.State == ConnectionState.Closed) conn.Open();

var dataTable = new DataTable();

var dataAdapter = new SqlDataAdapter(sql, conn);
dataAdapter.Fill(dataTable);


foreach (DataRow row in dataTable.Rows)
{
    var id = row["AccountID"].ToString();
    var name = row["Name"].ToString();
    var platform = row["platform"].ToString();

    long accountID;
    long.TryParse(id, out accountID);

    var dto = new AccountsByUserDTO { AccountID = accountID, Name = name + " (" + platform + ")" };
    dtoList.Add(dto);
}

Not recommended.

EF4 ObjectContext

var entityconn = (EntityConnection)db.Connection;
var sc = (SqlConnection) entityconn.StoreConnection;

bool doesHaveNaturalLinkage = false;
using (var connection = new SqlConnection(sc.ConnectionString))
{
    connection.Open();
    using (var command = new SqlCommand(@"SELECT DISTINCT a.ApplicationID, g.GroupID
                                            from infrastructure i
                                            inner join applicationinfrastructurelinks ail on ail.infrastructureid = i.infrastructureid and ail.worldbuilderlinkstatusid = 1 AND i.worldbuilderstatusid = 1
                                            inner join applications a on ail.applicationid = a.applicationid and a.WorldBuilderStatusID = 1
                                            inner join InfrastructureGroupLinks igl on igl.infrastructureid = i.infrastructureid and igl.worldbuilderlinkstatusid = 1
                                            inner join groups g on igl.groupid = g.groupid and g.worldbuilderstatusid = 1
                                            inner join ApplicationGroupLinks agl on agl.ApplicationID = a.ApplicationID AND agl.GroupID = g.GroupID
                                            WHERE agl.ApplicationGroupID = " + delegatedToAppGroupLink.ApplicationGroupID, connection))
    {
        using (var reader = command.ExecuteReader())
        {
            while (reader.Read())
            {
                doesHaveNaturalLinkage = true;
            }
        }
    }
}

Using ObjectContext.  Discussion on merits: http://stackoverflow.com/questions/6291716/how-to-populate-more-than-one-column-using-executescalar

if (command.ExecuteScalar() != null) doesHaveNaturalLinkage = true;

A more succinct way of executing.  If the query doesn’t return any data, ExecuteScalar will return null.  Handy.

| | # 
# Tuesday, 13 August 2013

http://stackoverflow.com/questions/5940225/fastest-way-of-inserting-in-entity-framework

  • Call SaveChanges() once after ALL records.
  • Call SaveChanges() after for example 100 records.
  • Call SaveChanges() after for example 100 records and dispose the context and create a new one.
  • Disable change detection

Inserting 6000 entities plus children takes 13s in debug mode running in a test runner.

xxxEntities.Configuration.AutoDetectChangesEnabled = false;

Debug.WriteLine(DateTime.Now);

for (int i = 1; i <= 6000; i++)
{
    var name = "Group" + i;
    var group = new Group
        {
            Name = name,
            PlatformID = 1,
            WorldBuilderStatusID = 1,
            AddedDate = DateTime.Now,
            LastSeenDate = DateTime.Now
        };
    // xxxEntites is codegenned from EF
    xxxEntities.Groups.Add(group);

    // Create ApplicationGroupLinks
    var agl = new ApplicationGroupLink
        {
            ApplicationID = ACBSAppID,
            Group = group,
            AddedDate = DateTime.Now,
            LastSeenDate = DateTime.Now,
            WorldBuilderLinkStatusID = 1
        };
    xxxEntities.ApplicationGroupLinks.Add(agl);

    var age = new ApplicationGroupEnvironment
        {
            ApplicationGroupLink = agl,
            DeploymentEnvironmentID = 1,
            AddedDate = DateTime.Now,
            LastSeenDate = DateTime.Now,
            WorldBuilderLinkStatusID = 1
        };
    xxxEntities.ApplicationGroupEnvironments.Add(age);

    var gal = new GroupAccountLink
        {
            Group = group,
            AccountID = TrotterGAccountID,
            AddedDate = DateTime.Now,
            LastSeenDate = DateTime.Now,
            WorldBuilderLinkStatusID = 1
        };
    xxxEntities.GroupAccountLinks.Add(gal);

    // Buffering the saves to stop out of memory exceptions in EF
    if (i%500 == 0)
        UEREntities.SaveChanges();
}
xxxEntities.SaveChanges();

This was within a DContext already.. and transaction scoping too.

| | # 
# Wednesday, 19 June 2013

 

image

Querying EF – Julie Lerman 2011

image
Eager loading is Include

image

image

Using a projection to eager load can be better as gets around All or Nothing.  So here am just getting the First order.

image
Using the context to eager load rather than a new query.

Lazy Loading

context.Configuration.LazyLoadingEnabled = true;

only navigation properties marked Virtual will be lazy loaded.

| | # 
# Tuesday, 18 June 2013

image
asdf

 

image
asdf

image
Wizard groups by schema name.

image
Each table must have an Entity Key

However the views dont have a primary key, so the wizard has inferred an entity key based on all the non nullable columns in table

image
A customer can have many CustomerAddresses and many SalesOrderHeaders

ICollection and virtual – a setup so can use lazy loading… see EF4.1 DbContext Data Access… Proxies, Change Tracking and Lazy Loading

Customisations in EF.. support parent child?

 

image
Group by Products, Customer, Sales and views are all olive colour

| | # 
# Monday, 17 June 2013

Getting AdventureWorks2008R2LT from http://msftdbprodsamples.codeplex.com/releases/view/59211

http://msftdbprodsamples.codeplex.com/Releases/  Scroll Down to AdventureWorks LT only 5MB
Needed the mdf and ldf files.  Then had to made sure permissions were not read only, and Everyone had full control to get imported into SQLServer.

image
Creating a blank solution, Class then AWModel.edmx

image
Name entities:  AWEntities

Julie Lerman has a custom db which will need to use the SQL Express LocalDB  file based attach of database.  **am now at a point where SQL Express 2012 wont install, nor update for VS2012.2.  And some updates for Win7 wont install.  Probably reinstall of machine.

| | # 
# Friday, 14 June 2013

image

Will cache query even if parameters change.

NuGet package contains 2 assemblies net4 and net45

image

image
We are targeting EF5 as there are Enum Types here.

 

image
note CodeFirst EF Power tool which will reverse engineer a db into ‘Code First’

| | # 
# 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

| | # 
# Monday, 04 March 2013
// called on every invoke - sleep useful for simulating lag
        public override object Invoke(InvokeDescription invokeDescription, out IEnumerable<System.ComponentModel.DataAnnotations.ValidationResult> validationErrors)
        {
            #if DEBUG
            System.Threading.Thread.Sleep(1000);
            #endif
            return base.Invoke(invokeDescription, out validationErrors);
        }

        // called on every query - sleep useful for simulating lag
        public override System.Collections.IEnumerable Query(QueryDescription queryDescription, out IEnumerable<System.ComponentModel.DataAnnotations.ValidationResult> validationErrors, out int totalCount)
        {
            #if DEBUG
            System.Threading.Thread.Sleep(1000);
            #endif
            return base.Query(queryDescription, out validationErrors, out totalCount);
        }

Used this to see the busyIndicators on my db locally and  to simulate lag.  This is in my DomainService class which is using EF4 and LinqToEntitiesDomainService

| | # 
# Tuesday, 26 February 2013

This helped hugely when testing over 2 contexts – an Enterprise Library direct call to SP, and Entitiy Framework call using RIA:

Base class for tests:

[TestClass]
    public class TransactedTestBasex
    {
        protected xxxClientAppUserEntitlementReviewEntities xxxEntities;
        protected FakexxxUserProvider fakeUserProvider;
        protected xxxClientAppDomainService xxxDomainService;
        //private TestDbTransaction _transaction;

        private TransactionScope scope;

        [TestInitialize()]
        public void TestStart()
        {
            if (xxxDomainService == null)
            {
                throw new NullReferenceException("Please ensure that you initialise xxxDomainService in the constructor of derived test class.");
            }

            scope = new TransactionScope(TransactionScopeOption.RequiresNew);

            //_transaction = xxxDomainService.BeginTransactionForUnitTest();
        }

        [TestCleanup()]
        public void TestEnd()
        {
            //_transaction.RollbackUnitTest();

            if (scope != null)
            {
                // NOTE: no call to scope.Complete();
                scope.Dispose();
            }
        }
    }

image

MSDTC is unavailable

1) check Distributed Transaction Coordinator in services is running.

| | # 
# 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

| | # 
# Monday, 27 August 2012

http://channel9.msdn.com/Events/TechEd/NorthAmerica/2012/DEV215  - June 14th 2012.  Adam Tuliper http://completedevelopment.blogspot.co.uk/

  • Patterns
  • Code-First
  • DB/Model First
  • Repo pattern
  • Code Migrations (4.3)

Why EF?

  • FAST Setup
  • Eager / Lazy loading
  • Validation

Tooling / Everything

Understanding EF

  • Context
    • All CRUD handles context
  • POCO
    • Persistent ignorant
    • Can contain business logics
    • Does not know anything about persistence
  • Entity States
    • Added
    • Detached
    • Unchanged
    • Modified

Model First/Database First

Pros

  • Visual designer
  • Easy code regen with model or db changes
  • Very fast

Cons

  • Some dont like XML based EDMX file.
  • Some feel loss of control without pure code
  • please use: DbContext Generator T4 templates

image
Installed EF5 in VS2010 – interestingly I get 4.4… this is against .NET4

Add new ADO.NET Entity Data Model.  Have got DB already.  Generate from Database.

image
Put together a simple database and used

image
Create the object so can F12 go to definition.

image
Code gen strategy was Default.

image

image
Code gen is none now.

In VS11 wont need to use the template trick.

image
The template creates nice POCO’s and a TuliperEntities Context which inherits off DbContext

image
How the POCOs get to the database

image

Code First

https://docs.google.com/file/d/0B5XxGi0aNE6bM1JNdm4tWDFUeWlDSHY1T3Nwd0xqQQ/edit# – Sample app of Adam’s from lslive Las Vegas

Pros

  • simple
  • specify initializers to create db
  • power is unit and integration testing
  • fluent api for clean attributes for validation

Cons

  • No visual designer
  • No direct SP support
  • power tools – can reverse engineer an existing db

image
Right click on project with EF Power Tools installed.  Reverse Engineer Code First.

image
Validation using Fluent API.

DataAnnotations – if want client side validation… jQuery unobtrusive validation..html5…if using ViewModels need to put dataannotations on the viewmodel.

or Custom Validators on Model or ViewModel.

“A lot of smart people, don’t do client side validation”

Global.asax

global action filters to catch concurrency … using AOP

timestamp

image

Data Migrations

can migrate model changes to database ie creates SQL

enable automatic migrations

update-database –script –verbose

Allows rollback into Migration table.

Testing

image

| | # 
# Sunday, 26 August 2012

Quickest way of getting something off the ground using CRUD. http://channel9.msdn.com/Events/MIX/MIX11/FRM13?format=auto   EF Code First, Steve Sanderson.

http://blog.stevensanderson.com/2011/01/13/scaffold-your-aspnet-mvc-3-project-with-the-mvcscaffolding-package/

image
Installed MVCScaffolding using NuGet.  Made a Model called Team, then issued the scaffolding command.

image
Full CRUD.  No repo pattern.

Changed the model to add another field, make DateTime nullable then how to change the database?  Blow it away!

image

Repo Pattern

Scaffold Controller Team –Repository -Force

Foreign Keys

http://weblogs.asp.net/kiyoshi/archive/2011/06/22/walkthrough-of-entity-framework-4-1-scaffolding-with-mvc-3-0-tools.aspx

image
A product can have a category

image

image

//Drops database and recreates if model changes
            System.Data.Entity.Database.SetInitializer(new System.Data.Entity.DropCreateDatabaseIfModelChanges<TestMVCApp2.Models.TestMVCApp2Context>());
| | # 

http://msdn.microsoft.com/en-us/data/gg702906

A 10 minute video on EF Model First

image
Navigation property allows to go from Blog to the Post, just using properties.

image
Right click on design surface and do Generate Database

image
Right click on designer and can do Run SQL.

image
Viewing database in Server Explorer in VS.

image
Using VS2010 so needed to D/l the DbContext Generator

Add Code Generation Item on design surface.

image
Created an Empty list of CRUD methods, and now creating views.

image
Wire up the Controller to the lightweight DbContext class created by the DbContext generator template (new in 4.1)

| | # 
# Monday, 26 September 2011
( Entity Framework | Massive | MVC | MVC3 | T4 | VidPub )

Use wordpress theme!

What is the business model?

  • Sell videos (ie download)
  • Sell access to the videos (ie stream)
  • Have small chunks ie episodes

What is our model (starting in baby steps)?

  • A Customer buys a Production
  • A Production is one or more Episodes
  • A Customer buys a Subscription
  • A Subscription gives access to Productions

so episodes cannot be purchased individually.

Write Tests

  1. CustomerSpecs
  2. SubscriptionSpecs
  3. ProductionSpecs
  4. EpisodeSpecs

Share them with the team as a discussion around business logic.

[TestFixture]
    public class CustomerSpecs : TestBase {
        [Test]
        public void a_user_should_be_able_to_add_production_to_cart() {
            this.IsPending();
        }

        [Test]
        public void a_user_that_owns_a_production_should_be_able_to_stream() {
            this.IsPending();
        }

        [Test]
        public void a_user_that_owns_a_production_should_be_able_to_download() {
            this.IsPending();
        }

        [Test]
        public void a_user_should_have_be_able_to_purchase_sub() {
            this.IsPending();
        }

        [Test]
        public void a_user_with_monthly_should_only_be_able_to_stream() {
            this.IsPending();
        }

        [Test]
        public void a_user_with_yearly_should_be_able_to_stream_and_download() {
            this.IsPending();
        }

        [Test]
        public void a_user_with_cancelled_sub_should_not_be_able_to_stream_or_download() {
            this.IsPending();
        }

        [Test]
        public void a_user_with_a_suspended_sub_should_not_be_able_to_stream_or_download() {
            this.IsPending();
        }

        [Test]
        public void a_user_with_overdue_sub_should_be_able_to_stream_or_download() {
            this.IsPending();
        }
        [Test]
        public void a_user_should_be_able_to_cancel_sub() {
            this.IsPending();
        }
        
    }
//A Subscription grants access over time
    //there is a monthly and a yearly
    //a monthly subscription offers stream only access
    //a yearly offers stream and download
    //a Customer can buy a subscription

    [TestFixture]
    public class SubscriptionSpecs : TestBase {

        [Test]
        public void a_subscription_is_only_valid_one_per_user() {
            this.IsPending();
        }

        [Test]
        public void a_subscription_can_be_pending_current_overdue_suspended_or_cancelled() {
            this.IsPending();
        }

        [Test]
        public void a_pending_subscription_can_turn_current() {
            this.IsPending();
        }

        [Test]
        public void a_current_subscription_can_become_overdue_if_payment_late() {
            this.IsPending();
        }

        [Test]
        public void an_overdue_subscription_can_become_current_if_payment_received_in_full() {
            this.IsPending();
        }

        [Test]
        public void an_overdue_subscription_can_become_suspended_if_payment_not_received_after_3_tries() {
            this.IsPending();
        }


        [Test]
        public void a_subscription_can_be_upgraded_from_monthly_to_annual() {
            this.IsPending();
        }

        [Test]
        public void a_subscription_cannot_be_downgraded_from_annual_to_monthly() {
            this.IsPending();
        }

    }
//A Production is a collection of Episodes
    //A Customer can buy a Production
    //A Customer cannot buy an individual episode

    [TestFixture]
    public class ProductionSpecs : TestBase {

        [Test]
        public void a_production_has_one_or_more_episodes() {
            this.IsPending();
        }

        [Test]
        public void a_production_can_cost_0_or_more_dollars() {
            this.IsPending();
        }

        [Test]
        public void a_production_can_be_in_production_published_suspended_or_offline() {
            this.IsPending();
        }

        [Test]
        public void a_production_is_viewable_if_not_offline() {
            this.IsPending();
        }

        [Test]
        public void a_production_can_be_downloaded_if_flagged() {
            this.IsPending();
        }


        [Test]
        public void episodes_can_be_released_offline_in_process() {
            this.IsPending();
        }
        
        [Test]
        public void episodes_are_viewable_if_released() {
            this.IsPending();
        }


        [Test]
        public void customers_can_see_notes_per_production() {
            this.IsPending();
        }

        [Test]
        public void customers_can_see_notes_per_episode() {
            this.IsPending();
        }

        [Test]
        public void customers_can_see_when_an_episode_and_production_was_released() {
            this.IsPending();
        }

        [Test]
        public void customers_can_see_who_authored_the_production() {
            this.IsPending();
        }

        [Test]
        public void customers_can_see_how_long_an_episode_is() {
            this.IsPending();
        }

        [Test]
        public void customers_can_see_total_duration_of_production() {
            this.IsPending();
        }
        

DB

DB First, Classes (or code) First, Migrations (from Rails world)

but .NET people don’t know migrations so leave for now.

EF Code-first

git checkout –b “codefirst”

EF Code-first

NuGet install in Web project.

Make classes with some properties:

public class Production {
        [Required]
        public string Title { get; set; }
        public string Description { get; set; }
        public decimal Price { get; set; }


    }

Rob isn’t a fan of DataAnnotations…messy.  More attributes than code… aren’t descriptive.. hard to refactor.

eg in AccountModel:

namespace VidPub.Web.Models {

    public class ChangePasswordModel {
        [Required]
        [DataType(DataType.Password)]
        [Display(Name = "Current password")]
        public string OldPassword { get; set; }

        [Required]
        [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
        [DataType(DataType.Password)]
        [Display(Name = "New password")]
        public string NewPassword { get; set; }

        [DataType(DataType.Password)]
        [Display(Name = "Confirm new password")]
        [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
        public string ConfirmPassword { get; set; }
    }

    public class LogOnModel {
        [Required]
        [Display(Name = "User name")]
        public string UserName { get; set; }

        [Required]
        [DataType(DataType.Password)]
        [Display(Name = "Password")]
        public string Password { get; set; }

        [Display(Name = "Remember me?")]
        public bool RememberMe { get; set; }
    }

setup DbContext:

namespace VidPub.Web.Models {
    public class VidpubDBContext : DbContext {
        public DbSet<Production> Productions { get; set; }
    }
}

Trick#1 – EF will try to use .\SQLExpress

image

No PK defined.

Guids as PK’s make DBA’s cry?

EF Conventions will use these as PK’s:

  • ProductionID
  • ID
namespace VidPub.Web.Models {
    public class Production {
        [Required]
        public int ID { get; set; }
        [Required]
        public string Title { get; set; }
        public string Description { get; set; }
        public decimal Price { get; set; }
    }
}

image

with no connection string defined we have our db created.

However its made the nvarchar(MAX) which isn’t good..

namespace VidPub.Web.Models {
    public class Production {
        [Required]
        public int ID { get; set; }
        [Required]
        [MaxLength(200)]
        public string Title { get; set; }
        public string Description { get; set; }
        public decimal Price { get; set; }
    }
}

however on recompile:

image

Tip #2: EF Code-first won’t run ALTER… its drop or recreate.

FK

    public class Production {
        [Required]
        public int ID { get; set; }
        [Required]
        public string Title { get; set; }
        public string Description { get; set; }
        public decimal Price { get; set; }
        public ICollection<Episode> Episodes { get; set; }
    }

    public class Episode {
        public int ID { get; set; }
        public string Title { get; set; }
        public string Description { get; set; }
        public int ProductionID { get; set; }
    }

and it gen’s up the database fine.

var db = new VidPub.Web.Models.VidpubDBContext();
            var p = new Production { Title = "My Production" };
            var e = new Episode { Title = "My Episode" };
            p.Episodes = new List<Episode>();
            p.Episodes.Add(e);
            db.Productions.Add(p);

            db.SaveChanges();

MVC Scaffolding

git checkout –b “scaffolding”

Install-Package MvcScaffolding

only have this in the model (no dbcontext from above)

namespace VidPub.Web.Models {
    public class Production {
        public int ID { get; set; }
        [Required]
        public string Title { get; set; }
        public string Description { get; set; }
        public decimal Price { get; set; }
        public ICollection<Episode> Episodes { get; set; }
    }

    public class Episode {
        public int ID { get; set; }
        public int ProductionID { get; set; }
        public string Title { get; set; }
    }
}
Scaffold Controller production
And it worked:
image
image

hmm – fast to go.. but even changes need to make eg varchar(max), database regens.. are going to get old v.soon.

Opinion

EF and Code-first… more work…in real world.

Make model in Database:

The less abstractions the better.. he loves rails activerecord.

Scaleable and Maintainable

More dev’s will know EF in the future years than anything else.

Good/Bad opinion of EF -

Massive

Bad – future hires won’t know it

Good

  • small and simple
  • high perf
  • this has worked for Rob in the past

Controller Design

Design RESTfully

REpresentational State Trasfer

“create an experience for a user that is predictable and understandable based on a url”

image

so now have a controller that is stubbed out and ready to go.

public class ProductionsController : Controller
    {
        Productions _table;
        public ProductionsController() {
            _table = new Productions();
        }

        public ActionResult Index()
        {
            return View(_table.All());
        }

then create a view:

image

fooling the tooling a bit as we’re going to be using dynamics, so chose any object.

image

Made db in the db! From the dbscript.sql file that came with VidPub.

So now we’ve got data reading from via Massive.

public class ProductionsController : Controller
    {
        Productions _table;
        public ProductionsController() {
            _table = new Productions();
        }

        public ActionResult Index()
        {
            return View(_table.All());
        }

via Massive (vidpub connection string in web.config)

public class Productions : DynamicModel {
        public Productions()
            : base("VidPub", "Productions", "ID") {
        }
<connectionStrings>
    <add name="VidPub" connectionString="server=.\;database=VidPub_Dev;integrated security=true" />

and rendered:

image

Views

[HttpPost]
        public ActionResult Create(FormCollection collection)
        {
            dynamic item = _table.CreateFrom(collection);
            try
            {
                _table.Insert(item);
                return RedirectToAction("Index");
            }
            catch
            {
                TempData["alert"] = "There was an error adding this item";
                return View();
            }
        }

CreateFrom creates a new Expando, white listed against the columns in the db.

Customizing the Generators - T4

As we can’t do @Html.TextBox(“title”, Model.Title)… extension methods and dynamics don’t play well together.

If we do string title = Model.Title then it all works.

image

This added a bunch of templates":

image

Then just took our ProductionsController code and put it into the template Controller.tt

<#@ template language="C#" HostSpecific="True" #>
<#
MvcTextTemplateHost mvcHost = (MvcTextTemplateHost)(Host);
#>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using VidPub.Web.Models;

<#
var controllerName = mvcHost.ControllerName;
var nameSpace = mvcHost.Namespace;
var tableName = controllerName.Replace("Controller", "");
#>

namespace <#= nameSpace #> {
public class <#= controllerName #> : Controller
    {
        dynamic _table;
        public <#= controllerName #>() {
            _table = new <#= tableName #>();
            ViewBag.Table = _table;
        }

        public ActionResult Index()
        {
            return View(_table.All());
        }

So now it generates much more cleanly.

namespace VidPub.Web.Controllers
{
    public class ProductionsController : ApplicationController
    {
        dynamic _table;
        public ProductionsController() {
            _table = new Productions();
            ViewBag.Table = _table;
        }

        public ActionResult Index()
        {
            return View(_table.All());
        }

        public ActionResult Details(int id)
        {
            return View(_table.FindBy(ID: id, schema: true));
        }

        public ActionResult Create()
        {
            return View(_table.Prototype);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create(FormCollection collection)
        {
            dynamic item = _table.CreateFrom(collection);
            try
            {
                _table.Insert(item);
                return RedirectToAction("Index");
            }
            catch
            {
                TempData["alert"] = "There was an error adding this item";
                return View();
            }
        }
        
        public ActionResult Edit(int id)
        {
            var model = _table.Get(ID: id);
            model._Table = _table;
            return View(model);
        }

        [HttpPost]
        public ActionResult Edit(int id, FormCollection collection)
        {
            var model = _table.CreateFrom(collection);
            try
            {
                _table.Update(model, id);
                return RedirectToAction("Index");
            }
            catch (Exception ex)
            {
                TempData["Error"] = "There was a problem editing this record";
                return View(model);
            }
        }

        public ActionResult Delete(int id)
        {
            return View();
        }


        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Delete(int id, FormCollection collection)
        {
            try
            {
                _table.Delete(id);
                return RedirectToAction("Index");
            }
            catch
            {
                TempData["Error"] = "There was a problem deleting this record";
                return View("Index");
            }
        }
    }
}

CruddyController

abstracting to a base class the cruddyness:

namespace VidPub.Web.Infrastructure {
    public class CruddyController : ApplicationController {
        // IoC will need to inject a tokenStore in everything that inhertis hmmmmmm
        public CruddyController(ITokenHandler tokenStore) : base(tokenStore) {}

        protected dynamic _table;

        //all virtual so can override if necessary
        public virtual ActionResult Index() {
            return View(_table.All());
        }

        public virtual ActionResult Details(int id) {
            return View(_table.FindBy(ID: id, schema: true));
        }

        public virtual ActionResult Create() {
            return View(_table.Prototype);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public virtual ActionResult Create(FormCollection collection) {
            dynamic item = _table.CreateFrom(collection);
            try {
                _table.Insert(item);
                return RedirectToAction("Index");
            }
            catch {
                TempData["alert"] = "There was an error adding this item";
                return View();
            }
        }

        public virtual ActionResult Edit(int id) {
            var model = _table.Get(ID: id);
            model._Table = _table;
            return View(model);
        }

        [HttpPost]
        public virtual ActionResult Edit(int id, FormCollection collection) {
            var model = _table.CreateFrom(collection);
            try {
                _table.Update(model, id);
                return RedirectToAction("Index");
            }
            catch (Exception ex) {
                TempData["Error"] = "There was a problem editing this record";
                return View(model);
            }
        }

        public virtual ActionResult Delete(int id) {
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public virtual ActionResult Delete(int id, FormCollection collection) {
            try {
                _table.Delete(id);
                return RedirectToAction("Index");
            }
            catch {
                TempData["Error"] = "There was a problem deleting this record";
                return View("Index");
            }
        }
    }
}

Review

  • Use what you know and get app to market
  • Big ORM in startup can get in the way
  • Build whats needed, no more
  • Avoided orm here
| | # 
# Saturday, 06 August 2011

NuGet installed EntityFramework and then SQLCE.

image

Had to type own code first Poco, and showing EF and SqlServerCe

Rename MyProductContect to ProductContext – just do it and press ctrl . (instead of F2)

image

Did full CRUD using EF Code First and SqlCE.

| | # 
# Monday, 14 March 2011

Downloaded EF CTP5 http://blogs.msdn.com/b/adonet/archive/2010/12/14/ef-feature-ctp5-released.aspx

Created a database and a model in EF

image

Added DbContext Generator (right click inside edmx file)

image

scaffold controller people –Force

Comment out generated dbcontext

Change peoplecontroller to point to new entities

image

Problem here is that FirstName is not required

image

yet in the model it is not nullable.

I can fix it by going to:

namespace EFTest.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

public partial class Person
{
// Primitive properties

public int PersonID { get; set; }
public int Age { get; set; }
public System.DateTime DateOfBirth { get; set; }
[Required]
public string FirstName { get; set; }

}
and adding in a Required field using DataAnnotations.

| | # 

Using VS2010. Create a model. 

image

this also puts in an entry into web.config

Create a controller

[HandleError]
public class CarsController : Controller
{

eftestEntities _db;

public CarsController()
{
_db = new eftestEntities();
}

//
// GET: /Cars/

public ActionResult Index()
{
var cars = _db.Cars.ToList();
return View(cars);
}

then right click and create a view:

image

I had to put data in the db, and only view works.

| | # 
# Friday, 11 March 2011

http://weblogs.asp.net/scottgu/archive/2010/07/16/code-first-development-with-entity-framework-4.aspx

http://weblogs.asp.net/scottgu/archive/2010/07/23/entity-framework-4-code-first-custom-database-schema-mapping.aspx

http://weblogs.asp.net/scottgu/archive/2010/08/03/using-ef-code-first-with-an-existing-database.aspx

Install-Package EFCodeFirst

Starting with a really simple example:

public class Dinner
{
public int DinnerID { get; set; }
public string Title { get; set; }
public DateTime EventDate { get; set; }
public string Address { get; set; }
public string HostedBy { get; set; }

then in DinnerController:

public class DinnerController : Controller
{
NerdDinnerReloadedContext context = new NerdDinnerReloadedContext();

//
// GET: /Dinner/

public ActionResult Index()
{
return View(context.Dinners.ToList());
}

//
// GET: /Dinner/Details/5

public ActionResult Details(int id)
{
return View();
}

//
// GET: /Dinner/Create

public ActionResult Create()
{
return View();
}

//
// POST: /Dinner/Create

[HttpPost]
public ActionResult Create(Dinner dinner)
{
if (ModelState.IsValid)
{
context.Dinners.Add(dinner);
context.SaveChanges();
return RedirectToAction("Index");
}

return View(dinner);
}

and the context:

public class NerdDinnerReloadedContext : DbContext
{
public DbSet<Dinner> Dinners { get; set; }

Very simple… and this does work, and will generate a database

image

Existing Database - Model First

Here I am defining my model

image

then wiring it up to the existing database

image

EF Code first uses a convention where context classes by default look for a connection string that has the same name as the context class.

image

The type 'MvcApplication1.Models.Cake' is not a supported entity type.

Possible helper: http://mvcscaffolding.codeplex.com/discussions/247163

| | #