csEntities

My experince with dynamic data entities

Very Basic Generics , LINQ and Solution to Eric Lippert’s Problem

Posted by ashwaniroy on January 17, 2010

It was lunch time was I was thinking of stepping out for a good lunch at Nando’s when a friend of mine sent me an email and he was taking about some issue he has come up with where in he has to order something . I said use generics . Well then I came across this puzzle on Eric’s blog (he is a Senior Dev in C# compiler team). The problem is mentioned here http://blogs.msdn.com/ericlippert/archive/2009/04/15/comma-quibbling.aspx

I decided to solve it and some how used generics , LINQ , Lambda expression and I thought my this blog can serve as a small pointer on how to use it in day to day programming. (For details on these please go to MSDN or somewhere else. This entry is just a demo of what these stuff look like and how can it be used in very simple terms)

So now the PROBLEM

Given a sequence of strings, concatenate them in a way similar to natural language.  For example the sequence "ABC", "DEF", "G", and "H" should be output as: {ABC, DEF, G and H}  "ABC" and "DEF" should be output as…   {ABC and DEF} and finally an empty sequence should yield the following output: {} . Now I am not going to handle the last bit that is the empty string part so just leave it.

So Here is the code (it is a console app and should work from VS 2008 onwards)

Code Snippet
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections;
  4. using System.Text;
  5. using System.Linq;
  6.  
  7. namespace intrestingCSharpe
  8. {
  9.  
  10.     public class mySortedList
  11.     {
  12.         private string _str;
  13.  
  14.         public string Str
  15.         {
  16.             get { return _str; }
  17.             set { _str = value; }
  18.         }
  19.         private int _pos;
  20.  
  21.         public int Pos
  22.         {
  23.             get { return _pos; }
  24.             set { _pos = value; }
  25.         }
  26.  
  27.  
  28.  
  29.  
  30.  
  31.     }
  32.     public class Program
  33.     {
  34.         public static int retAsciOfFirst(char ch)
  35.         {
  36.             return Convert.ToInt32(ch);
  37.         }
  38.  
  39.         static void Main(string[] args)
  40.         {
  41.  
  42.            List<string> sort = new List<string>();
  43.            sort.Add("ABC");
  44.            sort.Add("G");
  45.            sort.Add("DEF");
  46.            sort.Add("H");
  47.  
  48.  
  49.            List<mySortedList> sortedlist = new List<mySortedList>();
  50.  
  51.  
  52.            foreach (string s in sort)
  53.            {
  54.                mySortedList sorted = new mySortedList();
  55.                sorted.Str = s;
  56.                sorted.Pos = Convert.ToInt32(s.ToCharArray().GetValue(0));
  57.                sortedlist.Add(sorted);
  58.            }
  59.            IEnumerable<string> sortDescendingQuery =
  60.            from s in sortedlist
  61.            orderby s.Pos
  62.            select s.Str ;
  63.  
  64.            string contcatenator; int count = sortDescendingQuery.Count(); int counter = 1;
  65.  
  66.            foreach (string  s in sortDescendingQuery)
  67.            {
  68.  
  69.                if(counter == 1)
  70.                {
  71.                    contcatenator = "";
  72.                    Console.Write("{0}", "{"+contcatenator + s);
  73.                }
  74.                else if (counter > 1 && counter < count)
  75.                {
  76.                    contcatenator = ",";
  77.                    Console.Write("{0}", contcatenator + s);
  78.                }
  79.                else if (counter ==  count)
  80.                {
  81.                    contcatenator = " AND ";
  82.                    Console.Write("{0}", contcatenator + s+"}");
  83.                }
  84.  
  85.  
  86.  
  87.                counter++;
  88.  
  89.            }
  90.  
  91.             Console.Read();
  92.  
  93.         }
  94.     }
  95.  
  96. }

So some explanation now. I created a class(type) mySortedList which has 2 properties str and pos and I am using this class as the generic type. Generic list<T> needs a type so I can use my class. Handy here as I can store a list of my class type and enumerate over the collection and so on.

Now I have written a small LINQ query as well to do the ordering. It does the job. but a even better way will be to use the lambda expression to order this List<mySorterList>().

IMPROVEMET 1 : I will use a delegate to the ordering and not created another list but rather order the same list

So Here is the code . Just Comment the LINQ query and replace it with the delegate code till the end

Code Snippet
  1. sortedlist.Sort(delegate(mySortedList s1, mySortedList s2) { return s1.Pos.CompareTo(s2.Pos); });
  2.  
  3. string contcatenator; int count = sortedlist.Count(); int counter = 1;
  4.  
  5. foreach (mySortedList s in sortedlist)
  6. {
  7.  
  8.     if(counter == 1)
  9.     {
  10.         contcatenator = "";
  11.         Console.Write("{0}", "{"+contcatenator + s.Str);
  12.     }
  13.     else if (counter > 1 && counter < count)
  14.     {
  15.         contcatenator = ",";
  16.         Console.Write("{0}", contcatenator + s.Str);
  17.     }
  18.     else if (counter ==  count)
  19.     {
  20.         contcatenator = " AND ";
  21.         Console.Write("{0}", contcatenator + s.Str + "}");
  22.     }
  23.  
  24.  
  25.  
  26.     counter++;
  27.  
  28. }
  29.  
  30.  Console.Read();

 

Nice. But as I can use delegate here why not use LAMBDA Expression instead.

Just a small syntax explanation . Lambda expression are a functional programming construct and has been added to C# 3.0. The way it is written is

Sqr X => X*X meaning a function Sqr is a function of X which “goes to” X*X

ok so lets replace the above ordering by using lambda expression. The code becomes

I can replace the delegate by this

Code Snippet
  1. sortedlist.Sort((mySortedList p1, mySortedList p2) => p1.Pos.CompareTo(p2.Pos));

 

There are many other ways . I can use anonymous method to this sort return etc etc. So IN sort C#3.0 ‘s functional programming features like generics , LINQ , Lambda expressions , anonymous method are amazing . So do pay some attention to them to clean up your code written in frameworks 1.0 and 1.1 (2.0 has generics and anonymous method).

happy coding. and ya the output is (many other have used other way but I used ASCII encoding to have some more fun)

image

Posted in Uncategorized | Leave a Comment »

Writing Test Cases for Database Queries and Stored Procedure using VS 2010

Posted by ashwaniroy on December 19, 2009

I was playing around with a recently downloaded Beta 2 of VS 2010. As of me , I work a lot with Databases and Data warehouses but I did have an opportunity to work with C# based development using ADO.NET entity framework sometime back.

I am a big fan or writing test cases and making sure that I achieve a good code coverage. With VS 2010 I can write test cases for database objects like stored procedures. In this blog post I am going to write a very small bit about how you can write test cases for SQL Queries using VS 2010. (You don’t need any NUnit or csUnit as you might need in previous versions of VS and even in that case I don’t see an easy way as VS 2010 provides).

Start VS 2010 and go to ribbon on the top

image

Click New Test and select Database Unit Test

image

Configure the database connection string and Project name and other stuff

image

 

You will have a window which will look like this. Click on the CREATE NEW link

image

 

You can my TestMyProc.cs . This is a C# class. You can Paste you SQL code in the designer and the C# class will wrap this and execute it using ADO.NET . You need not worry writing the TESTFIXTURES and etc etc

The designer has this commented bit on top which is self explanatory.

/*
Add T-SQL statements here to exercise the database object
that you want to test.

To test a stored procedure, invoke it here by adding
an EXEC statement that has appropriate parameters.

In the lower pane, you can add test conditions that verify
whether the results of your T-SQL statements match what
you expect.
*/

Ok . Now lest write some test . Lets Begin with a negative on. Which Will fail.

I have configured my Database to connect to adventureworks.

The SQL Code I want to test is

SELECT * FROM HumanResources.Employee   WHERE BusinessEntityID  = 1 --will fail

Now go down to test condition panel. Here you can specify the conditions which will be based on what is the expected output. So Lets say I don’t expect any result set.

image

After you have configured the Condition you need to run this test.

image

The test result panel will have the below output stating that test has failed.

image

Now change the SQL Query to

SELECT * FROM HumanResources.Employee   WHERE BusinessEntityID  = -1 --will succeed

and run the test again. The test result panel will show PASSED

image

So we have written our first Unit Test to Test a SQL Query. The same thing can be extended to Stored Procedures. I don’t know as of now if it supports MDX unit testing out of the box but if go the code behind (F7) you will see a C# class. You can add ADOMD or AMO and test MDX , XMLA or anything else in theory. I have not tried it yet though.

Happy Test Driven Development for Database Guys!!. I will be blogging more on this.

Posted in C#, VS 2010 | Leave a Comment »

Visual Studio 2010 Beta 2 Out Now and it available for public download

Posted by ashwaniroy on October 22, 2009

You can download it from http://msdn.microsoft.com/en-gb/vstudio/dd582936.aspx . I have started download already yippee!!. Also watch out for my next series of VS 2010 blogs

image

Posted in VS 2010 | Tagged: | Leave a Comment »

Model Cleaner – ADO.NET entity cleaner

Posted by ashwaniroy on October 16, 2009

  1. Introduction to Dynamic Data Entity Web Application-Blog Post 1 
  2. Adding entiy Layer and scaffolding all tables and View – Blogpost 2
  3. Adding custom pages in Dynamic Data Web application- Blog Post 3
  4. Customizing Entity Partial Class (Rename Columns , Hide Specific Column and More System.ComponentModel.DataAnnotations attributes)- Blog Post 4
  5. Adding filter to the dynamic data application page – Blog post 5
  6. Customizing Detailsview Look and Feel- ModelPopup Extender — Blog post 6
  7. Customizing the Look and feel of Dynamic Data Fields using Field Template –Blog Post 7
  8. Adding Custom filters – Using advance filter repeater (Dynamic Data futures project from codeplex) - Blog post 8
  9. http://csentities.wordpress.com/2009/10/16/model-cleaner-ado-net-entity-cleaner/- Blogpost 9

 You can download the code to work with this blog post from here

There is a BUG or feature in the ADO.NET Entity framework . When you add a view to the EDMX layer it intuitively finds a bunch of columns and marks them as key . 

Lets have a look . Open the Codebook.Edmx and click top update model from database and add a view

image

 

The view definition does not contain the Keys. So the framework has no option rather than group by a bunch of keys and mark it as Entity Keys.

This new view has the following just after adding

image

If you look under the hood these are all the Not Nullable columns in that View definition.

 

BusinessEntityID no
Title yes
FirstName no
MiddleName yes
LastName no
Suffix yes
JobTitle no
Department no
GroupName no
StartDate no

 

Now Lets assume that the only Key in this View is BusinessEntityID , and I go ahead and right click on the rest of the columns and UNMARK rest of the columns as keys. I would expect that I have given enough instructions to the application . So I will go ahead and build the application . And BANG !! ERROR

image

 

Error    1    Error 3003: Problem in Mapping Fragment starting at line 307: All the key properties (vEmployeeDepartment.BusinessEntityID) of the EntitySet vEmployeeDepartment must be mapped to all the key properties (vEmployeeDepartment.BusinessEntityID, vEmployeeDepartment.Department, vEmployeeDepartment.FirstName, vEmployeeDepartment.GroupName, vEmployeeDepartment.JobTitle, vEmployeeDepartment.LastName, vEmployeeDepartment.StartDate) of table vEmployeeDepartment.
    D:\DynamicDataCodeBank\DynamicDataCodeBank\codebook.edmx    308    15    DynamicDataCodeBank

This is a real pain because now you will have to go to the XML and delete the fragments of XML nodes.  So lets right click on the EDMX and Open it with XML Editor. If you you go to the line this error is coming from you will see a bunch of Mapping underlined like the screen shot below

image

 

But this is not where the error is . The real error is there is  the Key is Defined for this Entity ( You might have to do a ctrl+ F to find this)

image

Now lets delete this. So it looks like this

image

 

Now when you build this solution the solution will nicely build. So far so good. But what – if and this is a Big onw

1. You have Many views in the database

2. You have More than one EDMX models

3. As we saw the error was in some other line and compilation threw error at some other line

4. What if what ever id did i.e 1. remove the keys and delete XML fragments can be automated . This will save a lot of time.

This is the purpose of the EDMX Cleaner.

 

Now I have  created this external tool and lets assume as of now that it works the way I want it to work . This is the screenshot of my Visual Studio where it is added as a external tool.

image

We will discuss the implementation later. For now lets assume that it works. When I click on this my output window display the following XML

 

Processing Entity vEmployee
Removed Node <PropertyRef Name=”FirstName” xmlns=”http://schemas.microsoft.com/ado/2006/04/edm/ssdl” />
Removed Node <PropertyRef Name=”LastName” xmlns=”http://schemas.microsoft.com/ado/2006/04/edm/ssdl” />
Removed Node <PropertyRef Name=”JobTitle” xmlns=”http://schemas.microsoft.com/ado/2006/04/edm/ssdl” />
Removed Node <PropertyRef Name=”EmailPromotion” xmlns=”http://schemas.microsoft.com/ado/2006/04/edm/ssdl” />
Removed Node <PropertyRef Name=”AddressLine1″ xmlns=”http://schemas.microsoft.com/ado/2006/04/edm/ssdl” />
Removed Node <PropertyRef Name=”City” xmlns=”http://schemas.microsoft.com/ado/2006/04/edm/ssdl” />
Removed Node <PropertyRef Name=”StateProvinceName” xmlns=”http://schemas.microsoft.com/ado/2006/04/edm/ssdl” />
Removed Node <PropertyRef Name=”PostalCode” xmlns=”http://schemas.microsoft.com/ado/2006/04/edm/ssdl” />
Removed Node <PropertyRef Name=”CountryRegionName” xmlns=”http://schemas.microsoft.com/ado/2006/04/edm/ssdl” />

 

As you can see above the nodes which were the junk keys which I had to manually remove has been removed by this tool.  So now lets look under the hood of what is this code made of.

It is a console application having 2 impoertants bits.

1. App.Config

2. Program.cs – the code holding the Main() event.

– App.config

You Entity Names and Number of keys . I have added the address table here and the Number of keys that it has.(1). Now may be not the ideal but this is how it works

–> If you have a view which has more than one keys then add this entity to this app.config file with the number of keys that this entity has. This program assumes that your key columns comes before other columns in the view. So if you say it has 2 keys it will assume that first 2 not nullable columns are the keys.

In most of the scenarios that I worked with I had my views just having one key. If that is the case all you need to do is to just add one table (any one table with one key). The program will use it throughout all the all the entities. Also the program assumes that you have open the EDMX file when it runs so that the current item is this XML file . This is the way this programs load this file. You can make it to find the EDMX in the solution  so that it is more clever but as of now it works.

You can always use this idea and build over it to work in a better way . The complete solution will be codeplex.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <!-- ADD THE TABLENAMES AND # of PKs below -->
    <add key="Address" value="1"/>

<add key="vEmployee" value="1"/>

  </appSettings>
</configuration>

 

Now if you look at the program.cs this is what it has. It is nothing more than finding the extra XML nodes and deleting the nodes.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.XPath;

namespace edmxKeyCleaner
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                Console.WriteLine("Please input the file path+name as an arguement");

            }
            else
            {
                string filePath = args[0];

                XmlDocument edmx = new XmlDocument();
                edmx.Load(filePath);
                edmx.Save(filePath + DateTime.Now.ToString("yyyyMMddHHmmss"));
                // Add the namespace.
                XmlNamespaceManager nsmgr = new XmlNamespaceManager(edmx.NameTable);
                nsmgr.AddNamespace("edmx", "<a href="http://schemas.microsoft.com/ado/2007/06/edmx">http://schemas.microsoft.com/ado/2007/06/edmx</a>");
                nsmgr.AddNamespace("store", "<a href="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator">http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator</a>");
                nsmgr.AddNamespace("ns", "<a href="http://schemas.microsoft.com/ado/2006/04/edm/ssdl">http://schemas.microsoft.com/ado/2006/04/edm/ssdl</a>");
                nsmgr.AddNamespace("ns2", "<a href="http://schemas.microsoft.com/ado/2006/04/edm">http://schemas.microsoft.com/ado/2006/04/edm</a>");
                KeyRemover(edmx, "ns", nsmgr);
                KeyRemover(edmx, "ns2", nsmgr);
                edmx.Save(filePath);
            }
        }

        private static void KeyRemover(XmlDocument edmx, string ns, XmlNamespaceManager nsmgr)
        {
            XmlNodeList entities = edmx.SelectNodes(string.Format("//{0}:EntityType", ns), nsmgr);

            foreach (XmlNode entity in entities)
            {
                XmlNodeList KeyList = entity.SelectNodes(string.Format("{0}:Key/{0}:PropertyRef", ns), nsmgr);
                if (KeyList.Count > 1)
                {

                    Console.WriteLine("Processing Entity {0}", entity.Attributes["Name"].Value);
                    int reqKeyCount = 1;
                    object val = System.Configuration.ConfigurationSettings.AppSettings[entity.Attributes["Name"].Value];
                    if (val != null && Convert.ToString(val) != string.Empty)
                    {
                        reqKeyCount = int.Parse(Convert.ToString(val));
                    }
                    for (int i = reqKeyCount; i < KeyList.Count; i++)
                    {
                        Console.WriteLine("Removed Node {0}", KeyList[i].ParentNode.RemoveChild(KeyList[i]).OuterXml);

                    }
                   
                }
            }
        }
    }
}

 

Now build this into the EXE file.

Add this as an external tool

1. Go to Visual Studio –> External tools

2. Add a new tool and configure it as shown in the screenshot below

image

 

 

1. You are done now . Now Open up the EDMX layer –> Update Model from Database and add a view (vEmployee in this case)

2. In this case lest assume the BusinessEntityID is only key . So go ahead and add to the app.config and then add this entity as no of keys =1

3.  Now keeping this EDMX open . Save the EDMX and go ahead and click on EDMX cleaner(Save before running this. Then only the changes will reflect)

image

4. Once you hit it

This is what your Output window looks like

image

 

Say Yes and it will load the new view with view on only one column which is the first column.

image

 

That’s it. You have your tool that cleans your EDMX layer by removing the unwanted fragments. This can be extended to make it more cleverer and work in some scenarios where the EDMX layers fails to clean itself but that is out of the scope of this blog.

You can download the application from here

Posted in Entity Framework | Tagged: | 3 Comments »

Adding Custom filters – Using advance filter repeater (Dynamic Data futures project from codeplex)

Posted by ashwaniroy on October 15, 2009

Contents

 Introduction to Dynamic Data Entity Web Application-Blog Post 1 

  1. Adding entiy Layer and scaffolding all tables and View – Blogpost 2
  2. Adding custom pages in Dynamic Data Web application- Blog Post 3
  3. Customizing Entity Partial Class (Rename Columns , Hide Specific Column and More System.ComponentModel.DataAnnotations attributes)- Blog Post 4
  4. Adding filter to the dynamic data application page – Blog post 5
  5. Customizing Detailsview Look and Feel- ModelPopup Extender — Blog post 6
  6. Customizing the Look and feel of Dynamic Data Fields using Field Template –Blog Post 7
  7. Adding Custom filters – Using advance filter repeater (Dynamic Data futures project from codeplex) - Blog post 8
  8. http://csentities.wordpress.com/2009/10/16/model-cleaner-ado-net-entity-cleaner/- Blogpost 9

 

In order to work with this blog you would need the code from the previous post. This can be download from here.

In the last post we saw how you can build your own field templates and customize the look and feel of your application . We have also seen your previous posts , how dynamic data creates a filter by default when you add a foreign key reference . Now in the real world you will have to add filters to columns other than foreign key columns and also you might want to hide the default filters which are created by foreign keys.

 

So now lets begin. In order to start with this you will need to down the dynamic data extension code . You can download this code from http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=14475 and then you unzip this you will see the . Even if you are not able to this blog has the both the code for Dynamic Data extensions and dll added to web application. So you can download that being from there.

Lets being it -

1. Go ahead and add the Dll reference to the Demo Application. So now you solution looks like this.

image

2. Now add a new folder the dynamic data folder and name it Filters

image

3. Now we are going to add a filter which has dropdownlist as control. SO right click on the folder and Add a new web user control just we did when we added the field template user control.

 

Now you need to go you the page where you need to add to ListDetails.aspx the following code

–> Comment the Filter repeater which is there by default . And add this Advance filter repeater control. Also there is Where parameter in the entity datasource. You will have to change it to the controlid of the advance filter repeater.

<%--            <asp:FilterRepeater ID="FilterRepeater" runat="server">
                <ItemTemplate>
                    <asp:Label runat="server" Text='<%# Eval("DisplayName") %>' AssociatedControlID="DynamicFilter$DropDownList1" />
                    <asp:DynamicFilter runat="server" ID="DynamicFilter" OnSelectedIndexChanged="OnFilterSelectedIndexChanged" />
                </ItemTemplate>
                <FooterTemplate><br /><br /></FooterTemplate>
            </asp:FilterRepeater>--%>
           
           
            <asp:AdvancedFilterRepeater id="AdvancedFilterRepeater" runat="server">
                    <HeaderTemplate>
                       
                    </HeaderTemplate>
                    <ItemTemplate>
                        <span><%# Eval("DisplayName") %>:<asp:DelegatingFilter runat="server" ID="DynamicFilter" OnSelectionChanged="OnFilterSelectedIndexChanged" /></span>
                       
                    </ItemTemplate>
                    <FooterTemplate>
                       
                    </FooterTemplate>
                </asp:AdvancedFilterRepeater>

    The entity datasource  should have this definition now

<asp:EntityDataSource ID="GridDataSource" runat="server" EnableDelete="true" EnableUpdate="true">
                <WhereParameters>
                    <asp:DynamicControlParameter ControlID="AdvancedFilterRepeater" />
                </WhereParameters>
            </asp:EntityDataSource>

Name this control as Default.  Now open the Default.aspx and paste this code in the designer

<%@ Control Language="C#" CodeFile="Default.ascx.cs" Inherits="DynamicDataCodeBank.Default_Filter" %>

<asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="true" EnableViewState="true" CssClass="filterdroplist">
    <asp:ListItem Text="All" Value="" />
</asp:DropDownList>

4. Now you would need to open the .aspx.cs and paste this code

using System;
using System.Linq;
using System.Linq.Expressions;
using System.Web.DynamicData;
using Microsoft.Web.DynamicData.Extensions;

namespace DynamicDataCodeBank
{
    public partial class Default_Filter : FilterUserControlBase, ISelectionChangedAware {
        public event EventHandler SelectionChanged {
            add {
                DropDownList1.SelectedIndexChanged += value;
            }
            remove {
                DropDownList1.SelectedIndexChanged -= value;
            }
        }

        protected void Page_Init(object sender, EventArgs e)
        {
            var items = Column.Table.GetQuery();

            // row
            var entityParam = Expression.Parameter(Column.Table.EntityType, "row");
            // row => row.Property
            var columnLambda = Expression.Lambda(Expression.Property(entityParam, Column.EntityTypeProperty), entityParam);
            // Items.Select(row => row.Property)
            var selectCall = Expression.Call(typeof(Queryable), "Select", new Type[] { items.ElementType, columnLambda.Body.Type }, items.Expression, columnLambda);
            // Items.Select(row => row.Property).Distinct
            var distinctCall = Expression.Call(typeof(Queryable), "Distinct", new Type[] { Column.EntityTypeProperty.PropertyType }, selectCall);

            var result = items.Provider.CreateQuery(distinctCall);

            foreach (var item in result)
            {
                DropDownList1.Items.Add(item.ToString());
            }
        }

        public override string SelectedValue
        {
            get
            {
                return DropDownList1.SelectedValue;
            }
        }
    }
}

If you notice this class inherits from FilterUserControlBase.  and implements ISelectionChangedAware interface.Filter control class inherits from UserControl . So in the end it is just a user control with me dynamic data ability like ability to understand Metatable and Metacolumn.

public partial class Default_Filter : FilterUserControlBase, ISelectionChangedAware
5. Ok now we have our user control. Now lets open the Address.cs entity template that we have created .

Add the namespace Microsoft.Web.DynamicData.Extension. Now just the like UIHint attribute you would be able to see the Filter attribute.

Your address.cs will look like this

using System;
using DynamicDataCodeBank;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Web.DynamicData;
using System.Web.UI;
using Microsoft.Web.DynamicData.Extensions;
namespace DynamicDataCodeBank
{
    [MetadataType(typeof(AddressMetadata))]
    [DisplayName("Address")]
   
    public partial class Address
    {
              
        public class AddressMetadata
        {
       

            [Filter(Enabled= true ,FilterControl= "Default")]
            public int AddressID { get; set; }

            [UIHint("MultilineText")]
            public string AddressLine1 { get; set; }
            public string AddressLine2 { get; set; }

            
            public string City { get; set; }
           
            [Filter(Enabled= false)]
            public int StateProvinceID { get; set; }
            public string PostalCode { get; set; }
            public object[] rowguid { get; set; }
            //[UIHint("MonthPicker")]
            //public DateTime ModifiedDate { get; set; }
            [UIHint("Calendar1")]
            public DateTime ModifiedDate { get; set; }
           
        }
    }
}
 

 

You have added a filter to the AddressID column , and removed the filter which was by default created on the StateprovinceID column. When you run this application you would see you screen looking like this.

image

 

You must also read this blog from MVP Steve Naughton http://csharpbits.notaclue.net/2008/09/dynamic-data-futures-advanced-filters.html

You can download it from here

Posted in Entity Framework | Tagged: | Leave a Comment »

Customizing the Look and feel of Dynamic Data Fields using Field Template

Posted by ashwaniroy on October 13, 2009

CONTENTS

  1. Introduction to Dynamic Data Entity Web Application-Blog Post 1 
  2. Adding entiy Layer and scaffolding all tables and View – Blogpost 2
  3. Adding custom pages in Dynamic Data Web application- Blog Post 3
  4. Customizing Entity Partial Class (Rename Columns , Hide Specific Column and More System.ComponentModel.DataAnnotations attributes)- Blog Post 4
  5. Adding filter to the dynamic data application page – Blog post 5
  6. Customizing Detailsview Look and Feel- ModelPopup Extender — Blog post 6
  7. Customizing the Look and feel of Dynamic Data Fields using Field Template –Blog Post 7
  8. Adding Custom filters – Using advance filter repeater (Dynamic Data futures project from codeplex) - Blog post 8

 

In order to work with this post you can download code from from here

Field templates are ASP.NET user controls that map data controls to data types in a data model.Field templates derive from FieldTemplateUserControl, the class that enables access to data fields, data columns, and metadata in data models. When you create a dynamic Data Application it creates some Field Templates. , but you can modify them or create custom field templates.

image

public partial class BooleanField : System.Web.DynamicData.FieldTemplateUserControl    { ……………….. }

 

A field template can then be used for customizing the Look and feel of dynamic Data controls. If you remember , in my Blog “Customizing Entity Partial Class” many different Annotations like DisplayName , DefaultValue etc. There is another very important one “UIHint”. We will see how we can use this along with field Template MultilineText  to make the textbox of the details as a multiline textbox instead of a normal text box.

Just an FYI. All the field templates has 2 user controls. UserContol.ascx and UserControl_Edit.ascx. You will see that for MultilineText there is just one . The reason for that is , in Non Edit mode of the details the control is a Literal (just a Label) so it does not have to have a separate user control. But just to keep the concept intact I will create a MultilineText.ascx as well.

So Here we go

1. Copy Text.ascx and Paste it in the same folder and rename it to Multiline.ascx. Now go the .aspx page and change the definition in Control tag to

&amp;amp;amp;lt;%@ Control Language=&amp;amp;amp;quot;C#&amp;amp;amp;quot; CodeBehind=&amp;amp;amp;quot;MultilineText.ascx.cs&amp;amp;amp;quot; Inherits=&amp;amp;amp;quot;DynamicDataCodeBank.MultilineText&amp;amp;amp;quot; %&amp;amp;amp;gt;

 

2. Go to the cSharp class and rename Text to MultilineText

 

3. Build the solution to make sure that all the namespace and class modification has been done properly.

 

4. Now go to EntityTemplates\Address.cs and replace Public string AddressLine1 to

[UIHint("MultilineText")]
public string AddressLine1 { get; set; }

 

So your class now looks like this

using System;   
using DynamicDataCodeBank;    
using System.ComponentModel;    
using System.ComponentModel.DataAnnotations;    
using System.Web.DynamicData;    
using System.Web.UI;    

namespace DynamicDataCodeBank   
{    
    [MetadataType(typeof(AddressMetadata))]    
    [DisplayName(&amp;amp;amp;quot;Address Page&amp;amp;amp;quot;)]    
    public partial class Address    
    {    
        public class AddressMetadata    
        {

            public int AddressID { get; set; }

            [UIHint(&amp;amp;amp;quot;MultilineText&amp;amp;amp;quot;)]   
            public string AddressLine1 { get; set; }    
            public string AddressLine2 { get; set; }    
            public string City { get; set; }    
            public int StateProvinceID { get; set; }    
            public string PostalCode { get; set; }    
            public object[] rowguid { get; set; }    
            public DateTime ModifiedDate { get; set; }

        }   
    }    
}

 

Run the Application . Open your address page. Click on SELECT to bring up the gridview and your page will look like this

image

 

That’s so cool. Without having to change anything in the page , just a mere decoration on attribute to look like a user control made the change. Now we know that FeildTempaltes can be used to look like a user control and this adds a lot of value to faster application development and user experience.

So once you have a bank of useful user controls you can customize the look and feel of your application very easily and consistently. Many of these user controls are available for download and I will also post some that I have used. But in order to understand a little more lest build a user control from scratch and use this as Field Template.

So in this example we will try to build a Calendar control which will have textbox and Calendar control and user should be able to click on this calendar button and pick a date which will be bound to the textbox. A Classic Calendar Control.

–>Calendar.ascx

1. Copy Text.ascx and Paste it in the same folder and rename it to Calendar.ascx. Now go the .aspx page and change the definition in Control tag to

&amp;amp;amp;lt;%@ Control CodeBehind=&amp;amp;amp;quot;Calendar.ascx.cs&amp;amp;amp;quot; Inherits=&amp;amp;amp;quot;DynamicDataCodeBank.Calendar&amp;amp;amp;quot; %&amp;amp;amp;gt;

 

2. Go to the cSharp class and rename Text to Calendar

 

3. Build the solution to make sure that all the namespace and class modification has been done properly.

 

Same as before because the calendar control in non-edit mode should look just like the Label (text.ascx)

 

—>Calendar_Edit.ascx

1. Right click on the Field Template folder and add new item. Then select WebUserControl

image

 

We Will be using AJAX Calendar Extender control to make this user control

1. In the .ASPX page paste this code


&amp;amp;amp;lt;%@ Control AutoEventWireup=&amp;amp;amp;quot;true&amp;amp;amp;quot; CodeBehind=&amp;amp;amp;quot;Calendar1_Edit.ascx.cs&amp;amp;amp;quot; Inherits=&amp;amp;amp;quot;DynamicDataCodeBank.Calendar1_Edit&amp;amp;amp;quot; %&amp;amp;amp;gt;

&amp;amp;amp;lt;%@ Register Assembly=&amp;amp;amp;quot;AjaxControlToolkit&amp;amp;amp;quot; Namespace=&amp;amp;amp;quot;AjaxControlToolkit&amp;amp;amp;quot; TagPrefix=&amp;amp;amp;quot;ajaxToolKit&amp;amp;amp;quot; %&amp;amp;amp;gt;   
&amp;amp;amp;lt;asp:TextBox runat=&amp;amp;amp;quot;server&amp;amp;amp;quot; Text = '&amp;amp;amp;lt;%# FieldValueEditString %&amp;amp;amp;gt;'&amp;amp;amp;gt;&amp;amp;amp;lt;/asp:TextBox&amp;amp;amp;gt;    
&amp;amp;amp;lt;asp:ImageButton runat=&amp;amp;amp;quot;server&amp;amp;amp;quot;    
    ImageUrl=&amp;amp;amp;quot;~/DynamicData/Content/Images/plus.gif&amp;amp;amp;quot; /&amp;amp;amp;gt;    
&amp;amp;amp;lt;ajaxToolKit:CalendarExtender runat = &amp;amp;amp;quot;server&amp;amp;amp;quot; TargetControlID = &amp;amp;amp;quot;TextBox1&amp;amp;amp;quot; PopupButtonID = &amp;amp;amp;quot;ImageButton1&amp;amp;amp;quot; Format = &amp;amp;amp;quot;dd/MM/yyyy&amp;amp;amp;quot; /&amp;amp;amp;gt;

&amp;amp;amp;lt;asp:RequiredFieldValidator runat=&amp;amp;amp;quot;server&amp;amp;amp;quot; CssClass=&amp;amp;amp;quot;droplist&amp;amp;amp;quot; ControlToValidate=&amp;amp;amp;quot;TextBox1&amp;amp;amp;quot; Display=&amp;amp;amp;quot;Dynamic&amp;amp;amp;quot; Enabled=&amp;amp;amp;quot;false&amp;amp;amp;quot; /&amp;amp;amp;gt;   
&amp;amp;amp;lt;asp:RegularExpressionValidator runat=&amp;amp;amp;quot;server&amp;amp;amp;quot; CssClass=&amp;amp;amp;quot;droplist&amp;amp;amp;quot; ControlToValidate=&amp;amp;amp;quot;TextBox1&amp;amp;amp;quot; Display=&amp;amp;amp;quot;Dynamic&amp;amp;amp;quot; Enabled=&amp;amp;amp;quot;false&amp;amp;amp;quot; /&amp;amp;amp;gt;    
&amp;amp;amp;lt;asp:DynamicValidator runat=&amp;amp;amp;quot;server&amp;amp;amp;quot; CssClass=&amp;amp;amp;quot;droplist&amp;amp;amp;quot; ControlToValidate=&amp;amp;amp;quot;TextBox1&amp;amp;amp;quot; Display=&amp;amp;amp;quot;Dynamic&amp;amp;amp;quot; /&amp;amp;amp;gt;

 

 

2. in the .aspc.cs paste this code

 

using System;   
using System.Data;    
using System.Configuration;    
using System.Collections;    
using System.Collections.Specialized;    
using System.Linq;    
using System.Web;    
using System.Web.Security;    
using System.Web.UI;    
using System.Web.UI.WebControls;    
using System.Web.UI.WebControls.WebParts;    
using System.Web.UI.HtmlControls;    
using System.Xml.Linq;    
using System.Web.DynamicData;

namespace DynamicDataCodeBank   
{    
    public partial class Calendar1_Edit : System.Web.DynamicData.FieldTemplateUserControl    
    {    
        protected void Page_Load(object sender, EventArgs e)    
        {    
            TextBox1.ToolTip = Column.Description;    
            SetUpValidator(RequiredFieldValidator1);    
            SetUpValidator(RegularExpressionValidator1);    
            SetUpValidator(DynamicValidator1);    
        }

        protected override void ExtractValues(IOrderedDictionary dictionary)   
        {    
            dictionary[Column.Name] = ConvertEditedValue(TextBox1.Text); 
        }

        public override Control DataControl   
        {    
            get    
            {    
                return TextBox1 ;    
            }    
        }    
    }    
}

 

3. Got to entity partial class and add this as UIHint to the ModifiedDate field

 


[UIHint(&amp;amp;amp;quot;Calendar1&amp;amp;amp;quot;)]   
public DateTime ModifiedDate { get; set; }
 

 

NOTE :- I have named it calendar1 because there was a user control with named calendar already which I download from a website. You may or may not use it but you will be able to see this in the download.

 

 

Now run the application and go to Address page and then click SELECT. You details view popup panel will look like this

image

 

That’s it. So now we understand how we can use Field Tempaltes and how can we create our own and use it in our application. There is vast amount of user controls compatible with dynamic data application already out there . You can download from Dynamic Data futures project from codeplex.

 

The notable difference from a normal user control is that this control inherits from System.Web.DynamicData.FieldTemplateUserControl and not from System.Web.UI.UserControl .  You can download this code from here.

Posted in Entity Framework | Tagged: | 1 Comment »

Customizing Detailsview Look and Feel- ModelPopup Extender

Posted by ashwaniroy on October 11, 2009

CONTENTS

  1. Introduction to Dynamic Data Entity Web Application-Blog Post 1 
  2. Adding entiy Layer and scaffolding all tables and View – Blogpost 2
  3. Adding custom pages in Dynamic Data Web application- Blog Post 3
  4. Customizing Entity Partial Class (Rename Columns , Hide Specific Column and More System.ComponentModel.DataAnnotations attributes)- Blog Post 4
  5. Adding filter to the dynamic data application page – Blog post 5
  6. Customizing Detailsview Look and Feel- ModelPopup Extender — Blog post 6

In order to work with this you would need the code from last blog post which you can download it from here.

This is not a dynamic data topic but it ties in to the series of blog posts. It is because now we are not only trying to understand the little bits of dynamic data but also trying to consolidate some other core concepts of related technology which has helped me will help you building a enterprise application.

So in this blog post we are trying to build upon the blog post 5 dynamic data code . Ok so her are the steps

1. Add reference to AjaxControlToolkit ( you can download it ). So this is how the solution will look like now.

image

2.  Register this in the page by adding this line in the .ASPX file

<%@ Register Assembly=”AjaxControlToolkit” Namespace=”AjaxControlToolkit” TagPrefix=”ajaxToolKit” %>

3.  Remove the Previous DetailsPanel and replace it by this code


&amp;amp;amp;lt;asp:Panel ID=&amp;amp;amp;quot;DetailsPanel&amp;amp;amp;quot; runat=&amp;amp;amp;quot;server&amp;amp;amp;quot; CssClass=&amp;amp;amp;quot;scrollMe&amp;amp;amp;quot; style=&amp;amp;amp;quot;display:none&amp;amp;amp;quot;&amp;amp;amp;gt;

&amp;amp;amp;lt;asp:UpdatePanel ID=&amp;amp;amp;quot;UpdatePanel2&amp;amp;amp;quot; runat=&amp;amp;amp;quot;server&amp;amp;amp;quot; UpdateMode=&amp;amp;amp;quot;Conditional&amp;amp;amp;quot;&amp;amp;amp;gt;

&amp;amp;amp;lt;ContentTemplate&amp;amp;amp;gt;

&amp;amp;amp;lt;asp:Button id=&amp;amp;amp;quot;ButtonShowPopup&amp;amp;amp;quot; runat=&amp;amp;amp;quot;server&amp;amp;amp;quot; style=&amp;amp;amp;quot;display:none&amp;amp;amp;quot; /&amp;amp;amp;gt;

&amp;amp;amp;lt;ajaxToolKit:ModalPopupExtender ID=&amp;amp;amp;quot;ModalPopupExtender1&amp;amp;amp;quot; runat=&amp;amp;amp;quot;server&amp;amp;amp;quot;

TargetControlID=&amp;amp;amp;quot;ButtonShowPopup&amp;amp;amp;quot; PopupControlID=&amp;amp;amp;quot;DetailsPanel&amp;amp;amp;quot;

CancelControlID=&amp;amp;amp;quot;LinkButtonCancel&amp;amp;amp;quot; BackgroundCssClass=&amp;amp;amp;quot;modalBackground&amp;amp;amp;quot;/&amp;amp;amp;gt;

&amp;amp;amp;lt;asp:ValidationSummary ID=&amp;amp;amp;quot;ValidationSummary1&amp;amp;amp;quot; runat=&amp;amp;amp;quot;server&amp;amp;amp;quot; EnableClientScript=&amp;amp;amp;quot;true&amp;amp;amp;quot;

HeaderText=&amp;amp;amp;quot;List of validation errors&amp;amp;amp;quot; /&amp;amp;amp;gt;

&amp;amp;amp;lt;asp:DynamicValidator runat=&amp;amp;amp;quot;server&amp;amp;amp;quot; ID=&amp;amp;amp;quot;DetailsViewValidator&amp;amp;amp;quot; ControlToValidate=&amp;amp;amp;quot;DetailsView1&amp;amp;amp;quot; Display=&amp;amp;amp;quot;None&amp;amp;amp;quot; /&amp;amp;amp;gt;

&amp;amp;amp;lt;asp:DetailsView ID=&amp;amp;amp;quot;DetailsView1&amp;amp;amp;quot; runat=&amp;amp;amp;quot;server&amp;amp;amp;quot; DataSourceID=&amp;amp;amp;quot;DetailsDataSource&amp;amp;amp;quot;

CssClass=&amp;amp;amp;quot;detailstable&amp;amp;amp;quot; FieldHeaderStyle-CssClass=&amp;amp;amp;quot;bold&amp;amp;amp;quot;

OnItemUpdated=&amp;amp;amp;quot;OnDetailsViewItemUpdated&amp;amp;amp;quot;

OnItemInserted=&amp;amp;amp;quot;OnDetailsViewItemInserted&amp;amp;amp;quot;

ondatabound=&amp;amp;amp;quot;DetailsView1_DataBound&amp;amp;amp;quot; onload=&amp;amp;amp;quot;DetailsView1_Load&amp;amp;amp;quot; &amp;amp;amp;gt;

&amp;amp;amp;lt;/asp:DetailsView&amp;amp;amp;gt;

&amp;amp;amp;lt;table class=&amp;amp;amp;quot;detailstable&amp;amp;amp;quot;&amp;amp;amp;gt;&amp;amp;amp;lt;tr&amp;amp;amp;gt;

&amp;amp;amp;lt;td&amp;amp;amp;gt;&amp;amp;amp;lt;asp:LinkButton ID=&amp;amp;amp;quot;LinkButtonSave&amp;amp;amp;quot; runat=&amp;amp;amp;quot;server&amp;amp;amp;quot; onclick=&amp;amp;amp;quot;LinkButtonSave_Click&amp;amp;amp;quot;&amp;amp;amp;gt;Save&amp;amp;amp;lt;/asp:LinkButton&amp;amp;amp;gt;&amp;amp;amp;lt;/td&amp;amp;amp;gt;

&amp;amp;amp;lt;td&amp;amp;amp;gt;&amp;amp;amp;lt;asp:LinkButton ID=&amp;amp;amp;quot;LinkButtonCancel&amp;amp;amp;quot; runat=&amp;amp;amp;quot;server&amp;amp;amp;quot; CausesValidation=&amp;amp;amp;quot;False&amp;amp;amp;quot;&amp;amp;amp;gt;Cancel&amp;amp;amp;lt;/asp:LinkButton&amp;amp;amp;gt;&amp;amp;amp;lt;/td&amp;amp;amp;gt;

&amp;amp;amp;lt;/tr&amp;amp;amp;gt;&amp;amp;amp;lt;/table&amp;amp;amp;gt;

&amp;amp;amp;lt;asp:EntityDataSource ID=&amp;amp;amp;quot;DetailsDataSource&amp;amp;amp;quot; runat=&amp;amp;amp;quot;server&amp;amp;amp;quot; EnableDelete=&amp;amp;amp;quot;true&amp;amp;amp;quot; EnableInsert=&amp;amp;amp;quot;true&amp;amp;amp;quot; EnableUpdate=&amp;amp;amp;quot;true&amp;amp;amp;quot;&amp;amp;amp;gt;

&amp;amp;amp;lt;WhereParameters&amp;amp;amp;gt;

&amp;amp;amp;lt;asp:DynamicControlParameter ControlID=&amp;amp;amp;quot;GridView1&amp;amp;amp;quot; /&amp;amp;amp;gt;

&amp;amp;amp;lt;/WhereParameters&amp;amp;amp;gt;

&amp;amp;amp;lt;/asp:EntityDataSource&amp;amp;amp;gt;

&amp;amp;amp;lt;/ContentTemplate&amp;amp;amp;gt;

&amp;amp;amp;lt;/asp:UpdatePanel&amp;amp;amp;gt;

&amp;amp;amp;lt;/asp:Panel&amp;amp;amp;gt;

 

4. Now Add this to the OnSelectedIndexChaning event of gridview. This will open the DetailsView in the popup


protected void OnGridViewSelectedIndexChanging(object sender, EventArgs e)

{

//GridView1.EditIndex = -1;

//DetailsView1.ChangeMode(DetailsViewMode.ReadOnly);

DetailsView1.ChangeMode(DetailsViewMode.Edit);

DetailsView1.DataBind();

UpdatePanel2.Update();

ModalPopupExtender1.Show();

}

 

 

5. Cool . Now the last thing . Add this to the Style.css . This will add a nice gray background when the popup opens.

 


.modalBackground
        {
            background-color:Gray;
            filter:alpha(opacity=70);
            opacity:0.7;
        }

 

Lets run the Application and see the result

image

 

6. We Do have a nice gray faded sort of backgroup and a nice popup which has SAVE and CANCEL. When you click Cancel the Model popup will close with just the set of code that we have already written. But we need to write SAVE

 


protected void LinkButtonSave_Click(object sender, EventArgs e)
 {
     if (IsValid)
     {
         if (DetailsView1.CurrentMode == DetailsViewMode.Insert)
         {
             DetailsView1.InsertItem(true);
         }
         else
         {
             DetailsView1.UpdateItem(true);
         }

         ModalPopupExtender1.Hide();
     }
 }

 

This is the wired up with Linkbutton Onclick event . This will enable you to you implement DetailsView Save.Before we do that we will also have to wireup a new event to Details view

Add this in .ASPX file OnItemUpdated=”OnDetailsViewItemUpdated”  and the below code in the ASPX.CS


protected void OnDetailsViewItemUpdated(object sender, DetailsViewUpdatedEventArgs e)
        {
            GridView1.DataBind();
        }

 

Now you SAVE functionality is implemented. We can implement the functionality in a similar way. So lets begin

1. Add a link button the fire the Model Popupextender


&amp;amp;amp;lt;div class=&amp;amp;amp;quot;bottomhyperlink&amp;amp;amp;quot;&amp;amp;amp;gt;
                &amp;amp;amp;lt;asp:LinkButton ID=&amp;amp;amp;quot;LinkButtonInsert&amp;amp;amp;quot; runat=&amp;amp;amp;quot;server&amp;amp;amp;quot; onclick=&amp;amp;amp;quot;LinkButtonInsert_Click&amp;amp;amp;quot; CausesValidation=&amp;amp;amp;quot;False&amp;amp;amp;quot;&amp;amp;amp;gt; &amp;amp;amp;lt;img id=&amp;amp;amp;quot;Img1&amp;amp;amp;quot; runat=&amp;amp;amp;quot;server&amp;amp;amp;quot; src=&amp;amp;amp;quot;~/DynamicData/Content/Images/plus.gif&amp;amp;amp;quot; alt=&amp;amp;amp;quot;Insert new item&amp;amp;amp;quot; /&amp;amp;amp;gt;Insert new item &amp;amp;amp;lt;/asp:LinkButton&amp;amp;amp;gt;
            &amp;amp;amp;lt;/div&amp;amp;amp;gt;

 

2. Now we need to add a event which fires up the Popup


protected void LinkButtonInsert_Click(object sender, EventArgs e)
{
    DetailsView1.ChangeMode(DetailsViewMode.Insert);
    DetailsView1.DataBind();

    UpdatePanel2.Update();

    ModalPopupExtender1.Show();
}

 

So we have INSERT / SAVE / CANCEL implemented for our own customized details view. We will work more on what we have built up and build more complex solution.

The code for the application till this blog can be downloaded from here

Posted in Entity Framework | Tagged: | 8 Comments »

Adding filter to the dynamic data application page – Blog post 5

Posted by ashwaniroy on October 7, 2009

CONTENTS

  1. Introduction to Dynamic Data Entity Web Application-Blog Post 1 
  2. Adding entiy Layer and scaffolding all tables and View – Blogpost 2
  3. Adding custom pages in Dynamic Data Web application- Blog Post 3
  4. Customizing Entity Partial Class (Rename Columns , Hide Specific Column and More System.ComponentModel.DataAnnotations attributes)- Blog Post 4
  5. Adding filter to the dynamic data application page – Blog post 5
  6. Customizing Detailsview Look and Feel- ModelPopup Extender — Blog post 6

 We will also learn how to add a simple 1 to Many relationship in a EDMX layer when working with tables.(With Views it is a bit different as there are no keys defined at database level you will have to Add Association in the EDMX but the concept is same)

In order to work with this step-by-step you need the previous blog’s application. You can download it from here

By default Dynamic Data provides a drop down list box for each foreign key and bool fields in a table. The drop down list allows you to filter the table with the value selected from the drop down list box. Lets have a look. Lets Add another table to EDMX which has foreign Key relationship to the existing Address Table.It is [Person].[StateProvince] from the adventureworks database.

 

Right Click on EDMX –> Update Model From Database –> select Person.StateProvince –> Finish

After this your EDMX will look like this.

image

OK So far so goo :) but when you run the application and click on the Address link you will get an error as shown below.

 

codebook.msl(42,6) : error 3007: Problem in Mapping Fragments starting at lines 6, 42: Non-Primary-Key column(s) [StateProvinceID] are being mapped in both fragments to different conceptual side properties – data inconsistency is possible because the corresponding conceptual side properties can be independently modified.

Description

 

It is very frustration as it does say a lot but does not make much sense. (I hope Microsoft Does something about this error but for now I will give a solution )

image

Lets look into the issue :- It is basically saying that StateProvince_ID is mapped more than once . It is mapped once in Foreign Key mapping as you can see in the first screenshot and if you right click on the table and look at table mapping you would see that the StateProvince_ID is mapped again.

image

So lets go and delete this from the EDMX layer(Just click on StateProvince_ID and delete) so now it looks like this

image

Now there is still something to do. If you remember we made a class for this Address in Entity templates\Address.cs. Since we deleted the Stateprovince_ID from entity we would have remove it from class as well. Well there is one more thing can be done. Rename the Fkey Navigation Property to Stateprovince_ID

 image

Now run the application. You will see the screen like the one below

image

With this note I will close this post. We will discuss about the advance filters in later posts. You can download the code for this blog post from here.

Posted in Entity Framework | Tagged: | 7 Comments »

Customizing Entity Partial Class (Rename Columns , Hide Specific Column and More System.ComponentModel.DataAnnotations attributes)- Blog Post 4

Posted by ashwaniroy on October 5, 2009

CONTENTS

  1. Introduction to Dynamic Data Entity Web Application-Blog Post 1 
  2. Adding entiy Layer and scaffolding all tables and View – Blogpost 2
  3. Adding custom pages in Dynamic Data Web application- Blog Post 3
  4. Customizing Entity Partial Class (Rename Columns , Hide Specific Column and More System.ComponentModel.DataAnnotations attributes)- Blog Post 4
  5. Adding filter to the dynamic data application page – Blog post 5
  6. Customizing Detailsview Look and Feel- ModelPopup Extender — Blog post 6

 

This is my 4th post of the series which is aimed at understanding and working with ADO.Net entity framework.In order to play with this code you would need the solution that has been developed as a part of Blog Post 3. You can down this from here.

First thing

1. Add a new folder in the application to contain this class

image

2. Add a new class to in this folder and Name it Address.cs

image

 

3. Now you if you remember from my second blog post the Address class has definition of

namespace DynamicDataCodeBank
{
    Partial Class Address{...}

}

So the class we are trying to add to decorate the Address class should have same signature. Here is the class


using System;
using DynamicDataCodeBank;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Web.DynamicData;
using System.Web.UI;

namespace DynamicDataCodeBank
{
    [MetadataType(typeof(AddressMetadata))]
    [DisplayName(&amp;amp;amp;quot;Address Page&amp;amp;amp;quot;)]
    public partial class Address
    {
        public class AddressMetadata
        {
            [UIHint(&amp;amp;amp;quot;ReadOnly&amp;amp;amp;quot;)]
            [DisplayName(&amp;amp;amp;quot;Ashwani's ID&amp;amp;amp;quot;)]
            public int AddressID { get; set; }
            public string AddressLine1 { get; set; }
            public string AddressLine2 { get; set; }
            public string City { get; set; }
            public int StateProvinceID { get; set; }
            [ScaffoldColumn(false)]
            public string PostalCode { get; set; }
            public object[] rowguid { get; set; }
            [ScaffoldColumn(false)]
            public DateTime ModifiedDate { get; set; }

        }
    }
}

 

Here is the output when you run this

image

Cool !! so now you know to customize the look and feel of the gridview and the columns that you want to show show in the details view.

(I had a requirement where I had to bind 4 columns in Gridview but the table to which I had bound the griview to had 20 columns and details view needed 16 colums. You can control it using the scaffold attribute of system.componentModel.DataAnnotations class attributes.

 

Click Edit to see what UIHint(“Readonly”) does… and there is much more that you can add to this class. For more information look on system.componentModel.DataAnnotations  at http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.aspx.

 

In next post we will explore FeildTemplates then Filters and then we will start writing custom FeildTemplates , Filters and other useful bits of dynamic data application.

You can download code till this Blog post from here.

Posted in Entity Framework | Tagged: | 8 Comments »

Adding custom pages in Dynamic Data Web application- Blog Post 3

Posted by ashwaniroy on October 4, 2009

CONTENTS

  1.  Introduction to Dynamic Data Entity Web Application-Blog Post 1  
  2. Adding entiy Layer and scaffolding all tables and View – Blogpost 2
  3. Adding custom pages in Dynamic Data Web application- Blog Post 3
  4. Customizing Entity Partial Class (Rename Columns , Hide Specific Column and More System.ComponentModel.DataAnnotations attributes)- Blog Post 4
  5. Adding filter to the dynamic data application page – Blog post 5
  6. Customizing Detailsview Look and Feel- ModelPopup Extender — Blog post 6

 

In Last post we discusses how you can use all the default and pre-coded stuff in a dynamic data web application to build a web application. But in a real-time application it is never enough. You always have to customize names of columns , number of columns  look and feel of gridview and details view and the list goes on and on……

As of now the page navigation works as per the routing and so we have Default.aspx –> ~/Address/ListDetails.aspx. This ListDetails.aspx is in the PageTemplates/ListDetails.aspx.

Now we will try to customize this by adding the page in CustomPages folder. After we have our own page for this Adress Page which no longer shared by other tables we can go ahead customize it as per the specific screen design requirement.

In this case we are going to hide the DELETE button which shows up by default in the default template Page

This is what you need to do

1. Add another table from Adventureworks database . I added AddressType.(This is just to demonstrate that address will use its custom page but if we dont add any custom page for address details it will still use the pagetemplate/ListDetails.aspx because its routing is not getting affected)

2. Add a new Folder under CustomPages with same Name as the entity that you want to customize. “Address in this case”.

3. Now copy List Details .aspx and past it in this new folder. This is how your solution explorer will look like now.

image

4. Now you will need to customize the page.

Go to this new ListDetails.aspx and change the page attribute to the one shown below.

&amp;amp;amp;lt;%@ Page Language=&amp;amp;amp;quot;C#&amp;amp;amp;quot; MasterPageFile=&amp;amp;amp;quot;~/Site.master&amp;amp;amp;quot; CodeBehind=&amp;amp;amp;quot;AddressListDetails.aspx.cs&amp;amp;amp;quot; Inherits=&amp;amp;amp;quot;DynamicDataCodeBank.AddressListDetails&amp;amp;amp;quot; %&amp;amp;amp;gt;

 

5. Go to this new ListDetails.aspx.cs and change the partial class ListDetails to

public partial class AddressListDetails : System.Web.UI.Page {......} 

6. Go to the ListDetails.aspx.designer.cs and do the same

There you have a custom page and whatever you do here will effect the look and feel of only Adress table’s view . So now In order to achieve the required go to Listdetails.aspx which is in this Address Folder and change the Gridview1 to

&amp;amp;amp;lt;asp:GridView ID=&amp;amp;amp;quot;GridView1&amp;amp;amp;quot; runat=&amp;amp;amp;quot;server&amp;amp;amp;quot; DataSourceID=&amp;amp;amp;quot;GridDataSource&amp;amp;amp;quot;   AutoGenerateSelectButton=&amp;amp;amp;quot;True&amp;amp;amp;quot; AutoGenerateEditButton=&amp;amp;amp;quot;True&amp;amp;amp;quot; AutoGenerateDeleteButton=&amp;amp;amp;quot;False&amp;amp;amp;quot; ......

 Now lets run the application and have a look if we achieved what we wanted. i.e Address page will not show DELETE button while AddressType will show DELETE button and the reason for that Address loads from this new page where delete button is turned off while Address Type loads from the default page which is PageTemplate/Listdetails.aspx , this page has all three buttons turned on.

 

here are the screen shots

image

This is the AddressType  page :- (shows SELECT / INSERT /DELETE )

image

This is the Address Page :- (shows SELECT and INSERT)

 

image

 

Cool !! so now that you have customize the Address page you can do more customizations like binding only selected columns to the Gridview1. Just turn off AutogenerateColumns = “false” and the bind the columns which you want. We will do that and customize details view in next blog post.

Have fun till then :)

NOTE: To work with examples you can down the code here

You will need adventure works database which you can download from codeplex. After which you will need to customize the connection as this colution will have my Laptop’s name

 

Posted in Entity Framework | Tagged: | 8 Comments »