Welcome to MSDN Blogs Sign in | Join | Help

Displaying WCF Data Service data in local reports

Its been sometime that I have blogged. I recently got asked by one of my peers on how to display the data from DataService on a local report and how to pass a parameter .

Its relatively easy to do this , the steps would be

  • Make a connection to the DataService using Data Service client API
  • Get the Data as a collection , my favorite List<T> :)
  • Add it to the ReportDataSource and bind it to the LocalReport

However, regarding the parameter passing , we know that if we add a parameter to the local report it does not prompt for the user and the developer is responsible for getting the value. Also you need to decide whether you need to get the entire data on the client and then do a filter on it or if  you want to get the filtered data from the server based on the parameter selected from the client. I took the former approach and get the entire data(considering the small amount of data that I have ). Here is how

I am assuming that you already have a neat WCF Data Service defined and ready to take the requests, in this case at http://localhost:54560/MyDataService/NorthwindService.svc/ . If you are new to this then I suggest you take a look at Getting Started with Data Services section on MSDN

 

In order to code the client lets first create a Data Service proxy using the tool DataSvcUtil.exe . Open up Visual Studio command prompt and type the following

c:\Users\bindeshv>DataSvcUtil /out:NorthwindService.cs /language:CSharp /uri:http://localhost:54560/MyDataService/NorthwindService.svc/

 

Next go ahead and add this to your WinForms project as an existing item. Once done you need to add the Using reference to the newly added chsarp namespace.

 

Add a RDLC file to the project as shown below

image

Next we need to define the data source for the local report. In order to do that bring up the Data Sources explore (from Visual Studio Menu , Data > Show Data Sources) and then click on Add New Data Source in the Data Source Explorer. This will start a wizard and in the first window choose Service as the Data Source type and in the next window type in the url of your WCF Data Service as shown below and click Go

 

 

image

Go ahead and give a namespace and then click on OK button.  Once the service reference is added to the project and since WCF Data Services exposes entity you need to choose the object that you will bind the report to. In order to do this again go to the Data Source Explorer and then Add a new Data Source but this time choose Object instead of service and point it to the WCF Service that was added to the project like shown below

 

image

Once the object is added to the Data Source Explore you can proceed with the normal design of the report by dragging in a table component and then adding the necessary fields

image

image

Now we need to add the Report Parameter, in this case I will specify the Employee ID as input for filtering , so that we see details of only one specific employee. In the Visual Studio Menu option go ahead and chose Report > Report Parameters..  and the required parameter

image

Once the parameter is defined you need to specify it in the Reports Table Properties Filter section as shown below

 

image

Once the filtering is done go ahead and add a Report Viewer control to the form. Remember we need to device our own parameter for Reports in case of local report. Here is how my form looks after the design is done

 

image

And here is how the code behind looks like

 

       //Form level member
       private List<Employees> empList = null ;
       private void Form1_Load(object sender, EventArgs e)
        {
            if (empList == null)
            {

                NorthwindModel.NorthwindEntities entitiesContext = new NorthwindModel.NorthwindEntities(new Uri("http://localhost:54560/MyDataService/NorthwindService.svc/"));
                try
                {

                   empList = (from emps in entitiesContext.Employees
                               select emps).ToList<Employees>();
                

                    ReportDataSource rds = new ReportDataSource("DataServiceForms_NorthwindReference_Employees", empList);
                    this.reportViewer1.LocalReport.DataSources.Clear();
                    this.reportViewer1.LocalReport.DataSources.Add(rds);

                }

                    
                catch (Exception _ex)
                {
                    MessageBox.Show(_ex.Message);

                }
            }

            //get all the employee ids and bind it 

            var empIDs = from emps in empList
                         select emps.EmployeeID;
            foreach (int i in empIDs)
            {
                this.comboBox1.Items.Add(i);
            }
            //set the combo to display the first item
            this.comboBox1.SelectedIndex = 0;

            //bind parameters to the report
            BindParameter();
        }

      private void BindParameter()
       {
           ReportParameter param = new ReportParameter("EmpID", this.comboBox1.SelectedItem.ToString());
           this.reportViewer1.LocalReport.SetParameters(new ReportParameter[] { param });
           this.reportViewer1.RefreshReport();
       }
       private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
       {
           BindParameter();
       }

The completed report looks like this

 

image

Until next post ..

Posted by bindeshv | 0 Comments
Filed under:

Referring ADO.Net Entity project in a different project

QuickPost:
I just now answered a question on the forum about one of the errors that might take you a while to figure out. Assume the following scenario, you have a Data Model Project designed as class library for EntityFramework and you have a middle layer or a UI Layer and you are referring the EF Assembly. When you try to run the project you get the  following error

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

If you go check the EntityProject you might find the connectionstring information inside the app.config. This is created automatically by the Entity Model Designer wizard. The issue is that when you refer the EntityProject inside another project the dll for the entity model is loaded in the context of the current application and hence it tries to read the connectionstring from the current app.config/web.config file.

The fix is to add the connectionstring information from the EntityProject  to your referring project’s app.config or web.config under the <connectionstrings> element , like this

<connectionStrings>
   <add name="SchoolEntities" connectionString="metadata=res://*/SchoolModel.csdl|res://*/SchoolModel.ssdl|res://*/SchoolModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=.\yukon;Initial Catalog=School;Integrated Security=True;MultipleActiveResultSets=True&quot;" providerName="System.Data.EntityClient" />
</connectionStrings>

Here is the forum post on this http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/d0261818-ed96-43b6-adfd-3c146d8e1a68/

 

Posted by bindeshv | 0 Comments
Filed under:

Using EntityBag with EntityFramework over WCF

I was going through the article published in MSDN by Daniel Simmons about the N-Tier Patterns http://msdn.microsoft.com/en-us/magazine/dd882522.aspx and came across the EntityBag implementation. So I went through couple of posts by Daniel on the EntityBag stuff to acquire the working knowledge and get started with EntityBag.  The project is hosted in codeplex

There were a couple of issues that I faced in getting it to run especially with changes in WCF and EF 3.5 sp1. So I thought of blogging about this to help get this working without much hassles.

Changes Needed In EntityBag

The first issue that you will face while compiling EntityBag project(Perseus) is the following error

  No overload for method 'GetEntityKey' takes '2' arguments        C:\Users\bindeshv\Code\perseus-1.1 entitybag\Perseus\UtilityExtensionMethods.cs     

The above error happens because ObjectContext.GetEntityKey(entitySetName, object) was a beta 3 method which was removed. Though there is an extension method inside UtilityExtensionMethod.cs  for IRleatedEnd like this

      public static EntityKey GetEntityKey(thisIRelatedEnd relatedEnd)
       {
           Debug.Assert(relatedEnd.IsEntityReference());
           TyperelationshipType = relatedEnd.GetType();
           PropertyInfo pi = relationshipType.GetProperty("EntityKey");
           return(EntityKey)pi.GetValue(relatedEnd, null);
       }

But the actual code calling this method is on ObjectContext in our CreateOriginalValuesObject method like this

      EntityKey targetKey = context.GetEntityKey(fullEntitySetName, target);

Since the intent here was to get the entity key for the target object and then get its ObjectStateEntry and then clone the original entries in the source to target, I changed the code to like this 

 

          // EntityKey targetKey = context.GetEntityKey(target);
            ObjectStateEntry targetStateEntry = context.ObjectStateManager.GetObjectStateEntry(target);
Changes In WCF Service

To test the program I created the following service contract and tried exposing it over WsHttpbinding

   [ServiceContract]
   public interface INorthwind
  {
      [OperationContract]
       EntityBag<NorthwindModel.Customers> GetCustomerByID(string customerID);

      [OperationContract]
      void UpdateCustomer(EntityBag<NorthwindModel.Customers> customers);

      [OperationContract] //for test
int Test(int p); }

But each time I tried getting this over to the client I will get a weird error on the client (took 2 days to figure this out)

An error occurred while receiving the HTTP response to http://binvij-admin2.fareast.corp.microsoft.com/NorthwindSVC/Northwind.svc. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more details.

Server stack trace:

   at System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException, HttpWebRequest request, HttpAbortReason abortReason)

   at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)

   at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)

   at System.ServiceModel.Channels.ClientReliableChannelBinder`1.RequestClientReliableChannelBinder`1.OnRequest(TRequestChannel channel, Message message, TimeSpan timeout, MaskingMode maskingMode)

   at System.ServiceModel.Channels.ClientReliableChannelBinder`1.Request(Message message, TimeSpan timeout, MaskingMode maskingMode)

   at System.ServiceModel.Channels.ClientReliableChannelBinder`1.Request(Message message, TimeSpan timeout)

   at System.ServiceModel.Security.SecuritySessionClientSettings`1.SecurityRequestSessionChannel.Request(Message message, TimeSpan timeout)

   at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)

   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)

   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)

   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)


I implemented a WCF trace, more details here on enabling the trace , and saw the following logged in

<ExceptionType>System.ServiceModel.CommunicationException, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>

<Message>There was an error while trying to serialize parameter http://tempuri.org/:GetCustomerByIDResult. The InnerException message was 'Type 'NorthwindModel.Customers' with data contract name 'Customers:http://schemas.datacontract.org/2004/07/NorthwindModel' is not expected. Add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.'. Please see InnerException for more details.</Message>

<StackTrace>at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeParameterPart(XmlDictionaryWriter writer, PartInfo part, Object graph) at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeParameter(XmlDictionaryWriter writer, PartInfo part, Object graph) at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeBody(XmlDictionaryWriter writer, MessageVersion version, String action, MessageDescription messageDescription, Object returnValue, Object[] parameters, Boolean isRequest) at System.ServiceModel.Dispatcher.OperationFormatter.SerializeBodyContents(XmlDictionaryWriter writer, MessageVersion version, Object[] parameters, Object returnValue, Boolean isRequest) at

 

The DataContractSerializer did not know about my Northwind.Customers type so I had to append my ServiceContract with

 [ServiceContract]
 [ServiceKnownType(typeof(NorthwindModel.Customers))]
 
  public interface INorthwind
  {
      [OperationContract]
     
      EntityBag<NorthwindModel.Customers> GetCustomerByID(string customerID);
Note: This is missing in the client test project for EntityBag in the  demo
After this I got an error at the client end, though I could see the WCF service sending the EntityBag<Customers> successfully. Here is the error
message

The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://tempuri.org/:GetCustomerByIDResult. The InnerException message was 'Error in line 1 position 1808. Element 'http://schemas.microsoft.com/2003/10/Serialization/Arrays:anyType' contains data of the 'http://schemas.datacontract.org/2004/07/NorthwindModel:Customers' data contract. The deserializer has no knowledge of any type that maps to this contract. Add the type corresponding to 'Customers' to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding it to the list of known types passed to DataContractSerializer.'.  Please see InnerException for more details.

Server stack trace:

   at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeParameterPart(XmlDictionaryReader reader, PartInfo part, Boolean isRequest)

   at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeBody(XmlDictionaryReader reader, MessageVersion version, String action, MessageDescription messageDescription, Object[] parameters, Boolean isRequest)

   at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeBodyContents(Message message, Object[] parameters, Boolean isRequest)

   at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeReply(Message message, Object[] parameters)

   at System.ServiceModel.Dispatcher.ProxyOperationRuntime.AfterReply(ProxyRpc& rpc)

   at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)

   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)

   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)

   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

 

We get this error due to an inappropriate setting of the buffer size for the binding in use. Check this link for more details
http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/e0bac3a6-f758-499b-9cab-32435b9887ea

The fix is to increase the messagesize for both the client and the service in the config file

         <wsHttpBinding>
         <binding name="AllowLargeMessages" maxReceivedMessageSize="512000" maxBufferPoolSize="512000" >
           <readerQuotas maxArrayLength="5000000" />
         </binding>
        </wsHttpBinding>

 

And this should help getting your EntityBag serialized and Deserialized.

Hope this helps !

Posted by bindeshv | 1 Comments
Filed under:

TechEd@Hyderabad-Day2

Could not post the details yesterday coz I was tired attending many sessions. Here are the major points from the sessions I attended

SQL Server 2008 -Beyond Relational Data by Praveen Srivatsa, Asthrasoft Consulting

XML Feature
We deal with most of the data that is Non Relational in nature

SQL Server 2008 has support for non relational data and it provides various data types

You can use XQuery with Xml type. This allows you to specify a schema as well so you have some control over the type being stored. In general the data can be stored in XML type and retrieved as a relational model or vice versa

Mapping of new date/time data types to xsd types

CLR Feature
Lots of queries around this feature from many people. And I got scared about this atleast from the Support aspect of it . Developers wanted to put many things as a CLR object. And below is my thought about this

Only 13 assemblies are allowed to be used called 'Blessed Assemblies'. UNSAFE load of an assembly can cause SQL Server memory corruption since it loads it inside MTL which is used for by sql server for external hosting of COM,CLR and out process providers

Filestreams
Benefits of filestream against BLOB types explained. Books OnLine(BOL) has more details on this.

 

ADO.NET Data Services Futures by Harish Ranganathan, Developer Evangelist

This talk was about ADO.Net Data Services offline still under development. Harish showed a smart client which can work offline. This is pretty pre-beta state. There were a lot of queries but most of them I believe would be clear if one goes through the ADO.Net synchronization services like one of the query was how does this handle a conflict of column  here is the MSDN page for this http://msdn.microsoft.com/en-us/library/bb726002.aspx 

One of the interesting questions asked in the session was :-

Can we keep version based copies of the modified records ? As of now I don’t this is thought about , but you can give your feedbacks on the Microsoft Connect site .

Modern Data Access Patterns and Implementations by Don Smith, Program Manager,P&P

This talk was an architect level discussion around the new patterns that should be incorporated for data access in particular with the DDD(Domain Driven Design). There is a lot being discussed about this in the P&P group and they are working on few patterns for data access, the code for which will be released once the VS 2010 beta is available. The pattern thats being explored are

  • Unit of work
  • ActiveRecords
  • Repository pattern

Check the codeplex site for more details http://www.codeplex.com/dataguidance

 

Building scalable applications using Velocity by Abid Khan, Program Manager, Velocity

Velocity is the new kid on the block was distributed caching. Many cool features in particular the load balancing. One of the internals is that this was purely build using .NET FX and leveraging the WCF as the backend for query over NamedPipes channel. Pretty much utilizes most of the concepts from clustering world and automatically detects any offline and online of hosted velocity server. Key takeaways

  • As of now it does not invalidate the cache and refresh itself from the database. Going forward this will be thought about
  • Please use a dedicated servers for velocity rather than clubbing it with the SQL Server or Web Farm
  • Velocity can be enabled for High Availability where in it will replicate the data across different hosted servers and thus available any time
  • Can be used in any .net client
Vision/Road Map
  • Being able to provide LINQ interfaces to query instead of the traditional get/put methods
  • Support for non .NET clients like PHP
  • Availability for HPC (High Performance Computing)

More details here at MSDN site http://msdn.microsoft.com/en-au/data/cc655792.aspx

 

until next post :)

Posted by bindeshv | 1 Comments
Filed under:

TechEd@Hyderabad-Day1

Today I attended TechED-09. Here are the updates from the sessions I attended and some of the interesting things I found out

ASP.NET 4.0 Features from Stephen Walther, Program Manager, ASP.NET
  • Source based development, more focus on a neater and readable code
  • Asp.net control’s client side ID code looked weird, so if you were using a client side script framework like JQuery it would be difficult to identify the control’s id in case a control lives inside a Master page. In ASP.Net 4.0 there is a property called {Control}.ControlID that will allow to the users to specify a more neater feature
  • Auto rendering of the code with "runat=server” attribute once picked from intelli sense  for common controls
  • <asp:formview> and <asp:listview> now allows you to render them in div mode apart from the traditional table mode
  • Viewstate can be disabled at the page level and then enabled for particular controls .  This is different from the EnableViewState mode since ViewState is inherited to the child controls whereas the EnableViewState does not
  • Response.Redirect was not SEO friendly and search engine had issues with indexing them . Now asp.net 4.0 enables you to use Response.PermanentRedirect which emits a status code that is recognized by Search Engines(i believe it is status code 301 if i am remembering this correctly)
  • New control added in asp.net 4 –>  QueryExtender . More about this here http://blogs.microsoft.co.il/blogs/bursteg/archive/2009/04/12/asp-net-queryextender-control-and-domaindatasource.aspx
  • Features added to ASP.Net Core are
    • Cache Extensibility using Velocity
    • Browser capabilities extensibility
    • Session state compression using 2 main industry standards . One of them is GZIP

Some of the interesting questions asked by attendees are and there answers by Stephen

  • Can i deploy ASP.NET application to the cloud(Microsoft Azure) ?
      You can use visual studio 2008 azure toolkit to deploy the applications to Azure
  • When do we use Silverlight vs ASP.NET Web Forms vs ASP.NET MVC vs ASP.Net Ajax
    These are targeted to different needs and hence different problems.
  • How can i combine some features from asp.net 4.0 and dynamic data . Can we club them ?
    Yes you can.
  • Check ASP.Net 4.0 and VS 2010 features White paper here http://www.asp.net/learn/whitepapers/aspnet40/
ASP.Net MVC from Stephen Walther

Well most of this talk was a walk through of a demo application and it was quite interesting. Some of the main features from MVC RTM that needs to be mentioned are

  • SEO based URLs
  • PartialAjaxUpdate
  • Velocity code templates available(this one refers to the java Velocity)
  • Create your own code generation for View creation using T4 templates
LINQ Deep Drive from Sanjay Vyas

This session was like starting from the beginning like how Linq works. So I am not going to spend time detailing it , there is plenty information already available on the net. I will post some interesting questions asked in the session and my answers to the same

  • Is the var keyword reflected at runtime ?
    No, the CompilerService actually converts it to a type but does not give it a name. It actually looks something like this  if you use ILDasm
  • class [System.Core]System.Func`2<int32,class '<>f__AnonymousType0`1'<int32>> LinqTest.Program::'CS$<>9__CachedAnonymousMethodDelegate4'

  • Can we use Linq for existing Datasets ?
    Yes, but only if you compile it with .net 3.5 framework. Here is more details about this on  MSDN http://msdn.microsoft.com/en-us/library/bb386977.aspx 
  • Whats the benefit of Property initializers , can’t i use constructors instead ?
    In a normal code you can but when you are writing a Linq Select statement and creating a new type the initializer becomes handy
  • Is the return type of the following query an IList<int> 

    List<int>list=newList<int>() {1,2,3,4,5};
                                                                   
              
    var res=from o in
    list                     
                        
    where o >
    2                       
                       
    select(new{iVal =o});       

        No, instead would be a type of IEnumerable<int>

  • Is there a performance hint while using Linq
    Not that we know of , but in case you find one, send us a repro code with the details of the delay  
  • What is the difference between IQueryable and IEnumerable
    Graphically put

    image

    Simply put IQueryable allows the mechanism for expression evaluation using queries. IEnumerator allows you to enumerate the collection. IQueryable on evaluation of a query expression gives you back a Enumerator for the resultant collection

Until next post :)

Posted by bindeshv | 1 Comments
Filed under:

Using Stored Procedures That Return Non Entity Type

In  the previous post I explained how to use a Stored Procedure in Entity Framework that returns an Entity Type.  However, if you try to map a stored procedure that is of a scalar type or returns an Array or List type then this won't work automatically with the current release of Entity Framework.

In order to get this working you might need to implement a partial class and then specify the method. So lets take a look at how to use a Sproc that returns a Distinct Country names from Northwind.Customers

CREATE PROCEDURE dbo.GetCountryList
AS
    BEGIN
     SET NOCOUNT ON 
      SELECT DISTINCT COUNTRY FROM CUSTOMERS ORDER BY COUNTRY ASC
     
  END 

 

First we might need to add the stored procedure inside the EDMX schema as we did in the previous stored procedure demo. So in the Model browser go ahead and the stored procedure by first adding it to Store Model and the adding the Function Import. Here is a screenshot

image

 

Notice that I have the return type as Scalar.  This will generate the following CSDL element

<FunctionImport Name="GetCountryList" ReturnType="Collection(String)" /></EntityContainer>

The return type element specify that its a Collection of String. Lets implement the partial class and write the code for calling the stored procedure

public partial class NorthwindEntities :global::System.Data.Objects.ObjectContext
 {
    /// <summary>
    /// Implementation for calling a method that returns distinct country list
    /// </summary>
    /// <returns>String collection </returns>
    public Collection<string> GetCountryList()
    {
        Collection<string> results = new Collection<string>();

        try
        {
            //get the connection object from the DataContext
            using (DbConnection conn = this.Connection)
            {
                DbCommand cmd = conn.CreateCommand();
                //command text is of the format of 'ContainerName.Stored Proc Name' 
                cmd.CommandText = String.Format("{0}.{1}", this.DefaultContainerName, "GetCountryList");
                cmd.CommandType = System.Data.CommandType.StoredProcedure;
                if (this.Connection.State != System.Data.ConnectionState.Open)
                {
                    this.Connection.Open();
                }

                var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess);
                while (reader.Read())
                {
                    results.Add((string)reader[0]);
                }

                return results;
            }
        }
        catch (Exception ex)
        {
            //Todo: meaning full exception handling 
        }



        return (Collection<string>)null;
       
    }
 }

Once this is compile you will be able to call this method from the front end using intellisense as shown in the screenshot below


image

Here is the code for forms binding

 

private void Form1_Load(object sender, EventArgs e)
       {
           using (NorthwindEntities entities = new NorthwindEntities())
           {
               this.customersBindingSource.DataSource = entities.CustByCountry("Germany");
               //bind the combo box
               //get the list of countries
               var countries = entities.GetCountryList();
               //for each country item in countries 
               foreach (var c in countries)
               {
                   //add the country name
                   this.toolStripComboBox1.Items.Add(c);

               }

           }
       }

 

And here is the output of the forms binding

image

Posted by bindeshv | 1 Comments
Filed under:

Using Stored Procedures in Entity Framework

Entity framework supports stored procedure. In this post I will explore how we can use stored procedures in entity framework.

I have created a Windows based application with Northwind database model(EDMX) . And have the Customer and Orders table selected.

image 

In order to add a stored procedure open up the Model Browser and right click on the Model.Store in this case NorthwindModel.Store

 

image

And choose the required stored procedure. Next right click anywhere on the Edmx designer and choose Add > Function Import.

 

image

This will bring up the wizard for adding Function. Choose the procedure you had added in the Model Store and choose the return type. In this case Customers which is of type Entity

image

This step will add a function to the EntityContext class. Here is how the generated code might look like

         /// <summary>
        /// There are no comments for NorthwindModel.CustByCountry in the schema.
        /// </summary>
        public global::System.Data.Objects.ObjectResult<Customers> CustByCountry(string country)
        {
            global::System.Data.Objects.ObjectParameter countryParameter;
            if ((country != null))
            {
                countryParameter = new global::System.Data.Objects.ObjectParameter("Country", country);
            }
            else
            {
                countryParameter = new global::System.Data.Objects.ObjectParameter("Country", typeof(string));
            }
            return base.ExecuteFunction<Customers>("CustByCountry", countryParameter);
        }

 

In my forms code I use an Object Data Source and have the following code for Forms_Load

          using (NorthwindEntities entities = new NorthwindEntities())
            {
                this.customersBindingSource.DataSource = entities.CustByCountry("Germany");
                
            }

Here is the output

image

Posted by bindeshv | 5 Comments
Filed under:

Getting Started With EntityClient in EntityFramework

In this post I am going to illustrate how to use EdmGen and EntityClient to program with Entity Framework.

EdmGen is utility shipped with Entity Framework for creation of the artifacts required for Entity Model Mapping viz the CSDL(Conceptual Schema Definition Language), SSDL(Storage Model) and MSL(Mapping Model). Though you can use the EDM wizard in Visual Studio 2008 sp1, but since you may find a lot of references how to use the EDM wizard on internet and really less information on usage of Edmgen, I resorted to this.

Lets see how to create the artifacts for our School Database Model. The School database can be generated from the scripts available at MSDN here. [Creating the School Sample Database http://msdn.microsoft.com/en-us/library/bb399731.aspx]

Open up Visual Studio 2008 Command Prompt and then fire the following command

c:\> edmgen /connectionstring:"server=.\yukon;integrated security=true;database=school" /mode:FullGeneration /project:"EntityClientDemo"

Here is the explanation of  the switches used with Edmgen.exe

  • /ConnectionString : specifies the connection string used for connecting to the database
  • /FullGeneration : Generate ssdl, msl, csdl, and objects from the database
  • /Project : The base name to use for the artifact files.

NOTE: You need to specify either this switch or all the /OutXXXXX switches if you are using the /FullGeneration switch. To get more details on the various switches use EdmGen -help

Next, go ahead and create a new project in Visual Studio 2008. For this post, I created a console application. And add reference System.Data.Entity.

Here is the code

 

using (EntityConnection conn = new EntityConnection())
           {
               try 
               {
                  conn.ConnectionString =
@"Metadata=C:\Users\BindeshV\Documents\Visual Studio 2008\Projects\EntityFramework\EFClientDemo\EFClientDemo\Artifacts;" + @"Provider=System.Data.SqlClient;"+ @"Provider Connection String='Server=.\yukon;Integrated Security=yes;Database=School'"; conn.Open(); EntityCommand cmd = conn.CreateCommand(); cmd.CommandText = "Select C.CourseID,C.Title from EFClientDemoContext.Course as C"; cmd.CommandType = CommandType.Text; EntityDataReader reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess); while(reader.Read()) { Console.WriteLine("Course Id={0} Course Title={1}",reader.GetInt32(0),reader.GetString(1)); } } catch(Exception ex) { Console.WriteLine(ex.StackTrace); } } Console.Read();

Usage of EntityClient is somewhat similar to that of the SqlClient.

The ConnectionString property of the EntityConnection object has 3 keywords

  • Metadata - The path where are the artifacts reside. In this case the .csdl,.ssdl and msl.
  • Provider - The ADO.NET provider used to connect to the Database Store
  • Provider Connection String - The regular connection string

Notice that the CommandText uses the format of ContainerName.EntityName . In our case the EdmGen tool had the following information for Container Name

<Schema Namespace="EFClientDemo" Alias="Self" xmlns="http://schemas.microsoft.com/ado/2006/04/edm">
  <EntityContainer Name="EFClientDemoContext">

Here is the output of the program

BlogEFClientDemoOutput

Thanks

Posted by bindeshv | 1 Comments
Filed under:

Retrieving Identity or AutoGenerated Column in ADO.NET

I recently handled an issue where customer was facing difficulty in picking up the Auto Generated primary key column in DataAdapter.Update() call. Looking around on the internet I saw many posts on the forums regarding how to get this value. So thought of posting it here

There are 2 ways to go about this

  • Using an output parameter
  • Using a Select statement inside the same batch as that of the insert

I see the output parameter being already documented in MSDN here http://msdn.microsoft.com/en-us/library/ks9f57t0.aspx.

The second method is documented like this MSDN and will be our topic of concern,

If your insert command executes a batch that includes both an INSERT statement and a SELECT statement that returns the new identity value, then you can retrieve the new value by setting the UpdatedRowSource property of the insert command to UpdateRowSource.FirstReturnedRecord

Here is how to go about this :

I have a sample table called Categories with the following schema

CategoriesTable

Here the CategoryId column is set to Identity

Next I created the stored procedure that will help insert the CategoryName column. Here is how the definition looks like

CREATE PROCEDURE InsertCategory
(
    @CategoryName nvarchar(50)
)
as
begin

    Insert Into Categories(CategoryName)
    values (@CategoryName)
    Select SCOPE_IDENTITY() as CategoryId
end

Notice that in the procedure the last T-SQL statement is a Select statement which queries the Identity value in the scope and returns it as the name of the column for the primary key.

Once this is in place lets take a look at the ADO.NET code

            string strCatName;
            Console.WriteLine("Enter the category");
            strCatName = Console.ReadLine();

            using (SqlConnection conn = new SqlConnection())
            {
                try
                {
                    conn.ConnectionString = @"Server=.\yukon;integrated security=true;initial catalog=Test";
                    conn.Open();

                    DataSet ds = new DataSet("Test");
                    //create an adapter specifying a select
                    SqlDataAdapter aDap = new SqlDataAdapter("Select * From Categories", conn);
                    //specify the insert command for the aDap
                    SqlCommand insertCommand = new SqlCommand();
                    insertCommand.CommandText = "InsertCategory";
                    insertCommand.CommandType = CommandType.StoredProcedure;
                    insertCommand.Parameters.Add("@CategoryName", SqlDbType.NVarChar, 50, "CategoryName");
                    insertCommand.UpdatedRowSource = UpdateRowSource.FirstReturnedRecord;
                    insertCommand.Connection = conn;
                    //bind the insertCommand to DataAdapter
                    aDap.InsertCommand = insertCommand;
                    //fill the dataset
                    aDap.Fill(ds, "Categories");

                    //get the Categories table
                    DataTable categoriesTbl = ds.Tables["Categories"];

                    //create a new row
                    DataRow newRow = categoriesTbl.NewRow();
                    //fill in the values for the column
                    newRow["CategoryName"] = strCatName;
                    //add the new row
                    categoriesTbl.Rows.Add(newRow);

                    //update the adapter
                    aDap.Update(ds, "Categories");

                    Console.WriteLine("Printing updated results");
                    PrintResults(ds);

                    Console.Read();


                }
                catch (SqlException ex)
                {
                    Console.WriteLine(ex.Message);
                    Console.Read();
                }

            }

Notice that in the insertCommand above I have the following property set

insertCommand.UpdatedRowSource = UpdateRowSource.FirstReturnedRecord;

This is specifying the adapter that once updated the first returned record is mapped to the changed row in DataSet. And since we are sending the CategoryId  which the DataTable already knows, the DataAdapter.Update() will be able to map the column and put the value for you.

Hope this helps !

Posted by bindeshv | 1 Comments
Filed under:

Web Client Software Factory-The Web Patterns

This post is in continuance with the last post  I had on WCSF. In this post I will briefly elaborate on various patterns in web development  and the general terms used to help you understand WCSF in a comprehensive way.

 

The View Presenter Pattern

Asp.Net is a great web development platform that enables you to be productive from day one. However, careful understanding of patterns is needed in order to program better.

I have been myself part of many projects where the code behind page will run into many lines of code, embedding the business logic and database calls. A generic pattern I have seen with many code behind pages is that they have the code for interaction for the user events, code to interact with the domain/database data and present it to the end user by databind calls. Though for a small project this might not be an issue at all, but in a enterprise level application, this approach, will end up having complex code behind making it difficult to test and maintain. The other concern here would be that I would need to rewrite or copy this entire stuff should I need them in other module(s).

The solution here is to go for View-Presenter. Separate the responsibilities for the visual display and the event handling behavior into different classes, the view and the presenter. The view class (.aspx.cs page) manages the controls on the page, and it forwards events to a presenter class. Once the presenter class gets the events it is responsible for communicating with the Business Logic Layer and responding back with the data/behavior to the View.

clip_image002

In the View-Presenter pattern the view does not know about the Model. The interaction with the Model is completely a responsibility of the Presenter. This makes it easy to have a TDD with Mock Implementations.

Two Important Patterns for implementing View Presenter

You can implement the View-Presenter using Observer Pattern or Application Controller pattern. In the Observer Pattern the Presenter listens to the events from the model and updates the corresponding events. The reference implementation of WCSF uses Application Controller pattern, explained in the next topic

The Application Controller Pattern

In the Application Controller pattern all the views interact with a single object which takes care of the page flow and the screen navigation logic. The Controller can also interact with the Model and define the flow based on the state of the Model.

clip_image004

Dependency Injection(IOC)

The better way to describe the issue would by showing a code snippet. Here we have a BankAccount object which tries to insert a debit amount

image

The issue with this approach here is the heavy dependency of DatabaseService class on SqlClient.The concerns here are

  • We need to rewrite the source code for DatabaseService.Insert to change the dependency from SqlClient to some other provider. Yes, I know that for most us this is not a changing factor, but lets say the product needs to be shipped to a client who wants to implement the backend as MySQL ?
  • The concrete implementation of the dependencies must be available at compile time.
  • The DatabaseService class is difficult to test in isolation because it has a direct reference to SqlClient (therefore, you cannot replace the service implementations with mock implementations).

We want to decouple the dependencies here so that we can replace/update the dependencies with minimal affect to the consumer and also help in Testing using mock implementations.  Dependency Injection comes to our help here. Here we have a Constructor Injection that will help us various implementations

image

image

image

image

Notice : I am having an inference of the Type of Database in use, this in order to build the appropriate collection syntax to pass inside the parameters. If the implementation used NHibernate or EFX any other ORM then this would not be needed. To demonstrate the concept this approach is simple.

Now that we have different implementations I can switch over to any provider neatly and efficiently and also test using Mock Object implementation of my choice.

image

Posted by bindeshv | 1 Comments
Filed under:

Web Client Software Factory-The Concept

 

In this series, I will help you get started with WCSF developed by Patterns and Practices team at Microsoft. If you are a web developer then this Software Factory will be of great help for you in your upcoming web projects.

Let me start of with the basics in order to speed you up with certain basic concepts which would be helpful to understand WCSF. Although the WCSF documentation is a great one, but if you are lazy as I am , you would not want to spend a lot of time in reading it but would be happy to see a quick get start on this.

Software Factory

A software factory is a proven set of standard industry practices based on Software Engineering Principles , that helps the architect build a uniform set of software assets and tools.

Software assets include reusable code components, documentation, and reference implementations. Software tools include wizards, code generators, and visual designers. Typically, a software factory provides templates and other tools to help a development team quickly start development of new applications. It also continues to assist the developers by providing guidance and automation of the prescribed development activities throughout the application development life cycle.

Guidance Package

Guidance Package consists of set of recipes and templates to allow developers to perform a set of development tasks defined by the package author. In the absence of this, the developer would have to do these tasks manually. Guidance Package enables the developer to automate these recipes. As an example Web Client Software Factory has a Recipe that allows the developer to add a View.

clip_image001

Composite Web Applications

Pictures talk more than the words. Here in this diagram we have different pieces of components that come together to give the user all the required features. However, the user does not know of the various components, since this is all integrated to one single web application to give an end user experience.

clip_image003

This entire principle is known as Composite Pattern.

Shell And Modules

A Composite Pattern generally divides the solution in to Shells and Modules. Shells are responsible for giving the user interface structure whereas the modules are functionality discrete pieces, integrate with user interface and communicate with Shells.

This helps in separation of concerns and thus helps in providing an environment for Test Driven Development and also helps separation of roles between developers.

Posted by bindeshv | 1 Comments
Filed under:

File IO System in .NET

I am preparing for MCTS Exam 70-536: Microsoft .NET Framework 2.0 - Application Development Foundation and came across the File IO System. So taking this opportunity here to post few details on the I/O streams to help understand the workings, specially for someone who is just getting started.

The following diagram below describes the I/O Class hierarchy in .Net Framework 2.0.

File IO System

Streams 

Represents the base class for many Stream based classes. Streams generally mean a sequence of bytes either flowing in to the system or flowing outside the system.

Specialised Streams These are streams specialized for a specific set of stream operations. Basically these streams inherit from the System.IO.Stream. The examples of such streams include :

  • System.IO.FileStream Represents a stream that can aid in reading and writing to a disk file or standard input or standard output.
  • System.IO.MemoryStream Represents a stream that can help in writing/reading to a memory location as a buffer, once the operation is done it can be transferred to another medium, perhaps to a disk file. MemoryStream's can reduce the need for temporary buffers or files in an application. 
  • System.IO.BufferedStream Represents a block of bytes in memory acting as a cache and helps reduce the call to Operating System. Once the buffer operation is done the bytes can be transferred to the appropriate medium.

 

Writers And Readers

These classes help in reading/writing to specialized streams. As shown in the above class diagram we have specialized readers and writers. For text related read/write operations we can use StreamReader or StreamWriter and StringReader and StringWriter classes. All of these classes inherits from TextReader and TextWriter abstract base class.

The StreamWriters or StreamReaders helps in writing or reading text streams to or from the underlying stream. Whereas the StringWriter or StringReader helps in writing or reading from inline memory strings.

Another special kind of readers and writers are the BinaryReader and BinaryWriter classes.These classes help in reading/writing binary data.

Steps In Reading/Writing
  1. The first step is to have a stream representing the medium to which you want to read/write the data
  2. Have an appropriate reader/writer depending upon the type of data you are interested in
  3. Use the readers/writers method to perform the data read/write operation
A Demo

Though you can get more specific details on reading and writing to a file however I would like to put few lines to indicate my above theory on basic steps in Reading/Writing a file. So here we go

   1:    Try
   2:          Dim theFile As FileStream
   3:          theFile = File.Create(fileName)
   4:           Dim sw As New StreamWriter(theFile)
   5:           sw.WriteLine("this is a file")
   6:           sw.Close()
   7:    Catch ex As Exception
   8:          Console.WriteLine(ex.Message)
   9:    End Try
Posted by bindeshv | 5 Comments
Filed under:

Demystifying SQL-Oracle Distributed Query Issues

While running the following query distributed query

select * from openrowset

('OraOLEDB.Oracle','oradb';'scott';'pwd1234$',

'select * from emp')

I got the following error message :

Msg 15281, Level 16, State 1, Line 1
SQL Server blocked access to STATEMENT 'OpenRowset/OpenDatasource' of component 'Ad Hoc Distributed Queries' because this component is turned off as part of the security configuration for this server. A system administrator can enable the use of 'Ad Hoc Distributed Queries' by using sp_configure. For more information about enabling 'Ad Hoc Distributed Queries', see "Surface Area Configuration" in SQL Server Books Online.

This is because by default in SQL Server 2005 Ad Hoc Queries are disabled. You can enable it by opening up SQL Server 2005 Configuration Wizard and click on Surface Area Configuration For Features and under Database Engine click Enable OPENROWSET and OPENDATASOURCE support.

 

image

 

You get the error

Msg 7399, Level 16, State 1, Line 3
The OLE DB provider "OraOLEDB.Oracle" for linked server "(null)" reported an error. The provider did not give any information about the error.
Msg 7330, Level 16, State 2, Line 3
Cannot fetch a row from OLE DB provider "OraOLEDB.Oracle" for linked server "(null)".

The reasons why you get this error  is because "Allow in Process" is not enabled for the provider. You can enable this option by opening up Linked Server > Providers and checking on "Allow in Process"

 

image

This option is needed because SQL Server will pass proper authentication across the remote procedure only when the Ole DB provider is configured for in process.

Posted by bindeshv | 2 Comments

C# 3.0 Features Basics For LINQ PART II

Continuing from part 1, here I will go one more step further and explain the language constructs basics in C# 3.0 which will help us in writing a LINQ query.

Lambda Expression Explained

In C# 2.0 you can write anonymous delegate methods that helps in reducing the amount of code written. To explain this, first I will demonstrate a simple code snippet that searches for a Contact based on the FirstName field using predicates in C#2.0

   1:  class Contact {
   2:        private String _firstName;
   3:      /* other fields go here   */
   4:         public String FirstName {
   5:           get {
   6:              if(_firstName != null) {
   7:              return _firstName;
   8:                }
   9:                              }
  10:           set {
  11:           _firstName = value;
  12:            }
  13:          }
  14:    }
Now lets get all the contacts stored, the GetAllContacts() can also be a call to Data Access Layer to get the values
   1:  List <Contact> myContacts = GetAllContacts();

Next we will use System.Collection.List<T>.FindAll to search for the contact based on FirstName. The MSDN documentation has the following information on the FindAll method

Retrieves the all the elements that match the conditions defined by the specified predicate.

Syntax

C#

public List<T> FindAll (
	Predicate<T> match
)
Parameters
match

The Predicate delegate that defines the conditions of the elements to search for.

Return Value

A List containing all the elements that match the conditions defined by the specified predicate, if found; otherwise, an empty List.

In our example :

   1:  List <Contact> contact = myContacts.FindAll( new Predicate<Contact> ( FirstNameFilter ) );
   2:   
   3:  //definition for FirstNameFilter
   4:   
   5:  static bool FirstNameFilter(Contact c) {
   6:      c.FirstName = "Bindesh";
   7:   }

Lets rewrite the code using C# 2.0 Anonymous method

   1:  List <Contact> contact = myContacts.FindAll( delegate(Contact c) { return c.FirstName = "Bindesh"} );
 
In the above code we have reduce the step to declare a method named FirstNameFilter through the introduction of anonynmous method. We will still further reduce the code by introducing Lambda expression
 
 
   1:  List <Contact> contact = myContacts.FindAll( c=>c.FirstName == "Bindesh");

So basically when when we have a lambda expression defined then we are inherently using delegates. Yes, I do agree that it takes a little while to get accustomed to this syntax, but for a good reason smile_regular
 
A lambda expression is of the format of :
 
(input parameter) => (statement);  //Called as statement lambda
(input parameter) => (expression);  //Called as expression lambda

 
 
The compiler will most of the times be able to infer the type of the input parameter and hence you need not specify one.
 
One important point that I want to mention here is that you can use lamda expression for custom defined delegates, if the lambda expression follows the rule i.e.
 
  • The lambda expression must contain same no. of parameters as defined in the delegate
  • The types of the parameter must be exactly/implicitly convertible to the corresponding delegate parameter
  • The return value of the lambda expression should be of the same type as the one mentioned in the delegate

 

Hope this gives you a basic idea of what is lamda expression and its evolution.  In my next blog I will explore more on extension methods, expression trees and queries.

catch you later ..

 

 

 

 
Posted by bindeshv | 1 Comments
Filed under:

C# 3.0 Features Basics For LINQ - PART 1

The 'var' Keyword

  1. Type inferred at compile time
  2. Can only be defined within method scope
  3. Mostly used when you need a variable for anonymous types which can only be resolved at compile time e.g. LINQ queries

Auto Implemented properties

This feature eases the creation of properties for a field inside the C# class  e.g.

   1:  //C# 3.0 Code 
   2:  class Contact
   3:  {
   4:      public string Phone { get; set; }
   5:      public string Name { get; set; }
   6:  }
In the above code, we create two properties.The compiler automatically creates a private variable here accessed only via getters and setters. 
In C# 2.0 we would write a considerably big code for achieving this :
   1:  //C# 2.0 Code 
   2:  Class Contact { 
   3:   private string _name;
   4:   public String Name {
   5:      get {
   6:          If(_name != null )  {
   7:              return _name;
   8:          }
   9:      set {
  10:          _name = value;
  11:      }
  12:  }
 

Making Sense Of Object Initializers

In C# 3.0 you can use object initializers to assign values to accessible fields/properties at the time of object creation e.g.

   1:  // C# 3.0;Object initializer for our Contact class 
   2:  Contact myContact = new Contact { Phone = '1212', Name = 'Bindesh' }; 

This is useful when we want to use the anonymous types , since the only way to initialize them are using object initializers . It also helps in selecting a portion of the data that is needed from all the available data in an class e.g.


 

   1:  class Contact {
   2:      public string FirstName { get; set; }
   3:      public string LastName { get;set;}
   4:      public string  Email {get;set;}
   5:      public string Phone {get;set;}
   6:  }
   7:  var contact = from c in Contacts
   8:             select new { c.FirstName, c.LastName, c.Email } ;
Collection Initializers

As is the case with object initializers, you can also have the Collections initialized in a short way, like

   1:  //C# 3.0;Collections Initializer
   2:  List <Contact> contacts = new List <Contact> { 
   3:                                              {'Bindesh', 'Vijayan'},
   4:                                              {'Madhuban', 'Singh'},
   5:                                              {'Sukesh', 'A K'}
   6:                                           };
The same would have taken a considerable work in C# 2.0, e.g.
   1:  List<Contact> contacts = new List<Contact>();
   2:  //call Add each time for adding values
   3:  contacts.Add( new Contact('Bindesh', 'Vijayan'));
The collection initializer can work for all the types that meets the following criteria :
  • Implements IEnumerable interface
  • Has a public Add() method

 

 
Posted by bindeshv | 1 Comments
Filed under:
More Posts Next page »
 
Page view tracker