Archive

Archive for May, 2010

The type DomainContext does not expose a method called ‘GetCustomer2Query’

May 26, 2010 1 comment

This error message was a common one that I was receiving when I switched from Linq2Sql to Linq2Entities. The reason behind this was that Linq2Sql pluralized my data model and so I was trying to look for the same corresponding query for Linq2Entities exposed by WCF RIA Services.

Here is the Xaml that causes the problem. It is valid Xaml but you will get a runtime error:

<UserControl
    x:Class="SampleView"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:riaCtls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.DomainServices"
    >
    <Grid >
        <riaCtls:DomainDataSource x:Name="_dds"
            QueryName="GetCustomer2Query"
            AutoLoad="False" PageSize="25" LoadSize="100"
            DomainContext="{Binding DomainContext, Mode=TwoWay}" />

        ...

    </Grid>
</UserControl>

At runtime, you will get the following error:

The type DomainContext does not expose a method called ‘GetCustomer2Query’

This message is simple to fix, all I did was correct the query as you can see below:

<UserControl
    x:Class="SampleView"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:riaCtls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.DomainServices"
    >
    <Grid >
        <riaCtls:DomainDataSource x:Name="_dds"
            QueryName="GetCustomerQuery"
            AutoLoad="False" PageSize="25" LoadSize="100"
            DomainContext="{Binding DomainContext, Mode=TwoWay}" />

        ...

    </Grid>
</UserControl>

The subtle difference is in the actual name of the query. This could be a blatant error or something as subtle as pluralization.

As a side note, the word “Query” can be ommitted. WCF RIA Services will honor the query name regardless.

Hope this helps…

DomainDataSource Changes – No more ControlParameter

May 26, 2010 3 comments

DomainDataSource Changes – No more ControlParameter

I have been slowly going through all of my existing Silverlight 3 modules that used RIA Services on top of Linq2Sql and I have been porting to Silverlight 4 using WCF RIA Services on top of Linq2Entities. One of the things that I encountered is that the ControlParameter is no longer available. This is actually a good thing since you can now accomplish the same thing with Databinding.

Here is an example of some Xaml where I had previously used the ControlParameter object.

<UserControl
    x:Class="SampleView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:riaCtls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Ria.Controls" 
    xmlns:riaData="clr-namespace:System.Windows.Data;assembly=System.Windows.Ria.Controls"
    >
    <Grid x:Name="LayoutRoot">
            
        <riaCtls:DomainDataSource x:Name="dds" QueryName="GetSl_d_DatabasesByAllButUserId">
            <riaCtls:DomainDataSource.QueryParameters>
                <riaData:ControlParameter ParameterName="userId"
                    ControlName="txtUserId"
                    PropertyName="Text" />
            </riaCtls:DomainDataSource.QueryParameters>
        </riaCtls:DomainDataSource>
        <TextBox x:Name="txtUserId" />
        ...
    </Grid>
</UserControl>

Now with the release of WCF RIA Services, you would write your Xaml as shown in the following example:

<UserControl
    x:Class="SampleView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:riaCtls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.DomainServices" 
    >
    <Grid x:Name="LayoutRoot">
            
        <riaCtls:DomainDataSource x:Name="dds" QueryName="GetSl_d_DatabasesByAllButUserId">
            <riaCtls:DomainDataSource.QueryParameters>
                <riaCtls:Parameter ParameterName="userId" 
                    Value="{Binding ElementName=txtUserId, Path=Text}" />
            </riaCtls:DomainDataSource.QueryParameters>
        </riaCtls:DomainDataSource>
        <TextBox x:Name="txtUserId" />
        ...
    </Grid>
</UserControl>

This adds a lot of extensibility and since we are just using databinding, we can now do binding to controls or bind to any property exposed on the ViewModel.

Hope this helps…

Dynamic Dashboards in Silverlight 4

Here are the slides from the presentation I did at the Charlotte ALT.NET group.

Hope you enjoy.

Categories: English Tags: , , ,

Building Business Applications with Silverlight 4 Slides uploaded

Here are the slides from my talk at the Greenville/Spartanburg Enterprise Developers Guild.

Hope you enjoy.

Categories: English Tags: ,

Code Camp 2010 Slides and Sample code uploaded

I have finally had some time to upload the slides and sample code for my sessions of Code Camp 2010.

Hope you enjoy.

Categories: English Tags: , , ,

Modifying a column with the Identity pattern is not supported.

In doing some testing today, I came across a wierd scenario with using WCF RIA Services on top of the Entity Framework. I was testing a Site table that had the following data definition:

CREATE TABLE Site
(
	  SiteIdent int identity NOT NULL
	, SiteKey varchar(4) primary key NOT NULL
	, MinimumPasswordLength int NOT NULL
	, RequirePasswordAuthentication bit NOT NULL
)

When I tried to make a modification to an existing record, I received the message in the title of my post:

“Modifying a column with the Identity pattern is not supported.”

One thing to note, I saw several other posts stating that this works with Entity Framework outside of WCF RIA Services. I verified that the StoreGeneratedPattern was set to “Identity” but it did not help. I also saw an entry in the msdn forums talking about creating a custom attribute.

Because I have control of the database, I made the following change to the data model to correct the issue:

CREATE TABLE Site
(
	  SiteIdent int identity primary key NOT NULL
	, SiteKey varchar(4) NOT NULL
	, MinimumPasswordLength int NOT NULL
	, RequirePasswordAuthentication bit NOT NULL
) ON [PRIMARY]
GO
CREATE UNIQUE NONCLUSTERED INDEX [IX_Site0] ON [dbo].[Site]
(
	[SiteKey] ASC
) ON [PRIMARY]

It is curious since I did not encounter this problem when I had previously used RIA Services on top of Linq2Sql. I am sure that there are several ways to resolve this issue but I wanted to show one way to getting past this issue.

Hope this helps….

Load operation failed for query ‘Getcustomer’. The metadata stored by the ObjectContext is different than the metadata stored by the ObjectContext’s connection. This can happen if the connection string is changed after the ObjectContext is created.

May 25, 2010 1 comment

This exception goes hand in hand with my previous blog posts on dynamically changing the connection string in Entity Framework. If you override CreateObjectContext(), you need to be sure that you don’t first create an instance of your entities and then try and pass in the connection string by setting the property.

The following is an example of what will cause the exception:

protected override CustomerEntities CreateObjectContext()
{
    string connectionString = ...
    ...
    ctx = new GrantsManagementEntities();
    ctx.Connection.ConnectionString = connectionString;

    return ctx;
}

Assuming we had a valid connection string, you would get the exception as listed in the title of this post.

The way to correct this issue is to do the following:

protected override CustomerEntities CreateObjectContext()
{
    string connectionString = ...
    ...
    ctx = new GrantsManagementEntities(connectionString);

    return ctx;
}

This allows for having dynamic connection strings on your WCF RIA Service.

Hope this helps…

The specified named connection is either not found in the configuration, not intended to be used with the EntityClient provider, or not valid.

May 25, 2010 15 comments

The specified named connection is either not found in the configuration, not intended to be used with the EntityClient provider, or not valid.

I wanted to share some bad with the good. I typically have a WCF RIA Services Class Library for every logical line of business in my enterprise application. With that said, I tend to have several libraries that are dedicated to different modules in my application.

When you create a new WCF RIA Services class library, it creates two projects. You get a project for the client and one for hosting the data access. One of the common mistakes I can make is to forget to copy the connection string information from the web project to the underlying hosting web application.

The title of this blog is the message from the exception that gets thrown if you forget to add the connection string entry in the underlying hosting web application web.config file.

This may not solve all of your problems with this exception but it is one to thing to remember.

Dynamic Dashboards in Silverlight 4

I had a great time speaking tonight about Dynamic Dashboards in Silverlight 4 at the Charlotte ALT.NET User Group. Thanks for all your participation and questions.

Categories: English Tags: , ,

Dynamically changing the connection string for WCF RIA Services Linq2Sql

In my last posts, I demonstrated how to provide a dynamic connection string for WCF RIA Services Linq2Entities. I will now show how this is done with Linq2Sql.

Okay, so you want to provide the ability to change the underlying connection string for a given WCF RIA Services request? The following is an example of creating a WCF RIA Services Class Library. I have also added a Linq2Sql classes model as well a DomainService Class.

WCF RIA Services - Linq2Sql

One thing that you will notice, is that I also manually created the DashboardDomainService.partial.vb file. It is in this class that I implement the ability to switch connection strings. I have found that since the other files are code generated, that by having my logic in a partial class, I can bypass the headache when I need to update or change my model and domain service.

The main class derives from LinqToSqlDomainService where T is the model we are building our DomainService. In this case it would be DashboardDataContext.

Let’s take a look at partial class now:

public partial class DashboardDomainService
{
    /// <summary>
    /// We need override this function since we are dynamically changing the
    /// connection string based on the user's session information.
    /// </summary>
    /// <returns></returns>
    protected override DashboardDataContext CreateDataContext()
    {
        DashboardDataContext ctx = null;
        if (!string.IsNullOrEmpty(ServiceContext.User.Identity.Name))
        {
            SecureLoginEntities sctx = new SecureLoginEntities();
            var userSession = (from c in sctx.sl_us_UserSession where
                c.sl_us_Token.HasValue.Equals(true) &&
                c.sl_us_Token.Value.Equals(new G
                    uid(ServiceContext.User.Identity.Name)) select
                c).FirstOrDefault();
            if (userSession != null)
            {
                sl_d_Database db = (from c in sctx.sl_d_Database where
                    c.sl_d_DatabaseIdent == userSession.sl_us_DatabaseId
                    select c).FirstOrDefault();
                if (db != null)
                {
                    // Initialize the connection string builder for the
                    // underlying provider.
                    SqlConnectionStringBuilder sqlBuilder =
                         new SqlConnectionStringBuilder();

                    // Set the properties for the data source.
                    sqlBuilder.DataSource = serverName;
                    sqlBuilder.InitialCatalog = databaseName;
                    sqlBuilder.IntegratedSecurity = false;
                    sqlBuilder.UserID = userName;
                    sqlBuilder.Password = password;

                    string connString = sqlBuilder.ToString();
                    ctx = new DashboardDataContext(connString);
                }
            }
        }

        return ctx;
    }

};

Basically what I want to happen is that whenever there is a request to this service, I want to override the CreateContext method and change the connection string accordingly. I have some authentication logic that I am using that helps me determine what database the user wants to use but once I get past that I basically create a new instance of my context passing in the newly created connection string.

For this example, I am building connection strings for SQL Server. I am using the SqlConnectionStringBuilder class. I then just call the ToString method to get the newly created connection string.

When all is said and done, you will get a connection string that looks like the following example taken from my Web.config:

<configuration>
  <connectionStrings>

    <add name="Common.Dashboard.Data.Web.My.MySettings.emgov_dataConnectionString"
        connectionString="Data Source=BUNKERHILL;
        Initial Catalog=emgov_data;User Id=emgovuser;Password=xxxx;"
        providerName="System.Data.SqlClient" />

  </connectionStrings>
  ...
<configuration>

(NOTE: I put break carriage return in this so that you could read it better but it would not be like this in your Web.config file.)

By following this example, you can now provide the ability to switch between connection string dynamically. You can even go as far as storing the connection information in a database and build the connection string on the fly as well.

Hope this helps…

Follow

Get every new post delivered to your Inbox.

Join 193 other followers