June 2007 Entries



Have you looked at or even heard of Mirosoft Acropolis yet?  It is suppose to be a type of RAD application builder primarily for business solutions.  Here is a an intersting overview of Acropolis:

http://blogs.msdn.com/brada/archive/2007/06/20/great-acropolis-explanations.aspx

Also check out:

http://windowsclient.net/acropolis/

 




Well, after a bit of work, Silverlight City (http://www.SilverlightCity.com) has finally launched.   It is basically a never ending thread of posts about blog posts, articles, or resources all about Silveright. 

Got some juicy info on Silverlight?  Drop by and add a post all about it! 

 




Plan on getting your feet wet in teh Linq waters?  There is a ton of information out, some old and some new with some just out-of-date.  Over the last week while digging into Linq, I found that simple information is rare while more advanced is fairly common.  As an example, I was looking for a way to issue a update to a single field in LInq 2 SQL without having to read the record first, modify it and then use the SubmitChanges() method.  Af a few hours of searching (was tired, it did not help), I found the obvious, that the DataContext has an ExecuteCommand and ExecuteQuery for just this type of thing.

So, here are a couple good quick articles to get you started:

http://www.codeproject.com/vista/LINQ_1.asp

http://www.codeproject.com/vista/LINQ2.asp

http://www.codeproject.com/vista/LINQ_3.asp

http://www.codeproject.com/csharp/lambdaexpressions.asp

Be sure to visit this one for some great short videos:

http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2007/05/10/9322.aspx





I ran into another problem with Linq and the Orcas beta 1 of Visual Studio.  It seems the code generated for your data classes may not contain a limiter on update checks which can give you the error:

"SQL Server does not handle comparison of NText, Text, Xml, or Image data types"

In my case, the field was a nText data type.  In the designer I can see that it is set to "Update Check" as "Never", but it appears that does not get saved in the code.  To solve the issue, I simply added the setting manually to the generated code on my field "PostText" such as:

[global::System.Data.Linq.Column(Storage="_PostText", Name="PostText", DBType="NText NOT NULL", CanBeNull=false)]

and changed it to:

[global::System.Data.Linq.Column(Storage="_PostText", Name="PostText", DBType="NText NOT NULL", CanBeNull=false, UpdateCheck=System.Data.Linq.UpdateCheck.Never)]

Seems to work fine, with the fix.  Will just have to remember using the Orcas Beta 1 to check whenever I get that error message!




Linq is pretty cool along with Linq 2 SQL.  Although  I have actually not read a great deal on Linq, I jumped in and started building out a  project to test the waters.  Much easier to see how much you can pick up before formal study.

Well, many things just clicked and I found quite of bit of it fairly easy.  Select, insert, update, delete all pretty easy.  For the project I did not want to turn to one SQL statement, no stored procedures or anything like that, just the Visual Studio Orcas and Linq.

I got hung up on a simple need, but the problem was directly related to a way of thinking such as the old SQL ways to the new Linq ways.  The simple little issue that hung me out to dry was simply grabbing the filtered count of records from a table.  Yep, that simple had me down for the count because I wanted the count but did not want to pull any records in order to get the count.

The problem is that my method of thought is that if I build out a query and assign its results, that is a call to the database.  Actually, that is not the point the call is made, but rather when the data in that results is enumerated.  That got me stuck. 

The simple answer would be like:

int count = (from r in db.MyPeopleTable
                    where p.IsMale == true
                    select r).Count();

In my old line of thought, the query portion would execute and then the Count aggregate would run against the records returned, thus pulling all those matching records over the wire.  Actually, that is not what really happens.  It may have been easier for me to understand if I would have used a Lambda expression for it such as:

int count = db.MyPeopleTable.Where( r => r.isMale == true).Count();

In this example, it does not have a formal "select", so I might have got it right at the start.  It does not exacly look like it will bring any records over the wire, just the count.  Yep, both versions work exactly the same which is to request a count of records matching the "where" clause. 

Well, that was another one of the many learning experiences.  I am thinking that I might stick more with Lamda versions for a while as they seem a bit clearer, at least in this instance.  As for the project, this was the only real issue I ran into, the rest went pretty easy using Linq for all database access in a clean multi-tier application!

 




Although I have been working with .NET 3.5 and the Orcas for a little bit, I did not happen upon a cool feature of C# 3.0.  Automatic Properties.

In the old days of C# (for most of us, within the last six months) we would write a propery such as:

private int myProperty;

public int MyProperty
{
     get
     {
          return myProperty;
     }

     set
     {
          myProperty = value;
     }
}

While it is trivial, this has taken up some time just in typing, not to mention code making the code longer. 

Well, C# 3.0 now comes with Automatic Properties that you can define such as:

public int MyProperty { get; set; }

That is the same as the previous method.  It keeps the private varible internally so you no longer have to clutter your code with it.  The only downside to automatic properites is that you cannot have a read-only property, all automatic properties must have a get and set.  I wonder why I must type them in if there are required, why not just default them? 

Anyway, even though you cannot have a "read-only" property in the sense it does not have a "set" defined, you can however restrict the 'set' part by prefixing it with a restriction such as protected, private, etc. :

public int MyProperty { get; private set ; }

For the most part, this is a read-only property as far as the world outside your class is concerned, the code outside your class cannot access the setter method of the property, but they can access the getter.  So, your class is the only one that can access the setter.

Now all that is pretty cool, but another addition equally cool is the new Object Initializers.

Let us say we have the class:

public class EmailMessage
{
     public string From { get; set; }
     public string To { get; set; }
     public string Subject { get; set; }
     public string Body { get; set; }
}

You could create an instance of the class and fill the values one-by-one such as:

EmailMessage em = new EMailMessage();
em.From = "BigDaddy@YouWantMe.com";
em.To = "YouWho@SayItIsSo.com";
em.Subject = "Lets Meet";
em.Body = "See you tonight at 10pm!";

Of course you could build a constructor that took those values and stuffed them in the properties, but with Object Initializers, you could just write the code as:

EmailMessage em = new EMailMessage
                                               {
                                                      From = ""BigDaddy@YouWantMe.com",
                                                           To =  "YouWho@SayItIsSo.com", 
                                                  Subject = "Lets Meet",
                                                      Body = "See you tonight at 10pm!"
                                               };


Of course, you could supply those properties in any order or leave out ones you did not want to set!

Guess I will have to do a bit of research and see what other featuers I am missing out on ;)




Well, today I was working on building out he SIlverlightCity website and instead of using my old dataset/table adapter mehtods of the past in my data layer, I decided I would play a bit with Linq 2 SQL and see how it worked out.  After a few minutes, I can see I will not need to mess around with dataset/table adapter stuff for most work, Linq more than fits the bill.

It is so easy to query, update, delete, etc, without all the extra work, not to mention that the Linq to SQL designer in the Orcas 1 beta is pretty simple to work with.  The paging of data is also simple, which I am sure will come in handy many times in the future!

With all the wonderful technology that the next version of Visual Studio  will be using, it is hard to imagine the development world in just a couple of years..  That will give them a year to get up and running with all this great technology and the applications and services generated by developers should really raise the bar on feature rich, quality software!

If you have not played around with Linq before, here are a couple great helpers to get you on your way:

http://weblogs.asp.net/scottgu/archive/ 2007/05/19/ using-linq-to-sql-part-1.aspx

http://weblogs.asp.net/scottgu/archive/ 2007/05/29/ linq-to-sql-part-2-defining-our- data-model-classes.aspx

http://mtaulty.com/CommunityServer/blogs/ mike_taultys_ blog/archive/2007/ 05/10/9322.aspx




The next version of Visual Studio will bring all kinds of new goodies.  One is .NET 3.5 (maybe 4.0 by then) which will include two new controls for ASP.NET developers, the ListView and DataPager controls.  My first look at these controls had a few errors, but I quickly go the idea.  Here is the example I tried, which simply reads my RSS feed from http://blog.silverlightcity.com and displays the items.

The first step is to create the web form and then drag a DataPager control and the ListView control followed by another DataPager control.  I configured the ListView control to use an XMLDataSource which I set the DataFile property to my RSS feed and the xpath property to "/rss/channel/item".  That is all that is required for the data source to read all the items in my RSS feed.

The next step is to set the layouttemplate and the item tempate for the Listview control.  The layouttemplate specifies the overall look where the items will be embedded.  Think of the layouttemplate as a master page (nothing to do with a master page, but functions like one as far as the ListView is concerned by specifying the look of the control) and the itemtemplate as the formatted content that will be inserted into the area specified in the layouttemplate.  The itemtemplate governs the appearance of items and the layout dictates the look of the container that holds the items.   Here is the code for the ListView: 


<asp:ListView ID="ListView1" runat="server" DataSourceID="XmlTheFeed" ItemContainerID="DataSection" >

<layouttemplate>
<
br /><br />We are here:<br /><br />
<
div id="DataSection" runat="server"></div>
</layouttemplate>

<itemtemplate>
<
h2><a href='<%# XPath("link") %>'><%# XPath("title") %></a></h2>
<
p><em>Published <%#XPath("pubDate")%></em></p>
<
p><%# XPath("description") %></p>
<
br />
</
itemtemplate>

<ItemSeparatorTemplate>
<
div style="height:0px;border-top:dashed 1px #ff0000"></div>
</
ItemSeparatorTemplate>

</asp:ListView>

<asp:XmlDataSource ID="XmlTheFeed" runat="server" DataFile="http://blog.silverlightcity.com/Rss.aspx"
XPath="/rss/channel/item"></asp:XmlDataSource>


Notice the use of the "DataSection" label.  It is first used in the "ItemContainerID" property of the ListView and then again as the ID of the div I made in the layouttemplate section.  Also notice the div mentioned, is set to RunAt="Server".  This is what specifies "where" the list of items will appear.  In this example, all items will be inserted into the div that has the "DataSection" ID.  So, you can see the layouttemplate for the control is a type of skin and the ItemContainerID property of the control specifies the control where the items are to be inserted.  Be sure the control where you want the items inserted is flagged to runat="Server".

With the above code on a page, you should be able to display the RSS feed.  If there is an error make sure the register line was generated at the top of the page:

<%@ Register assembly="System.Web.Extensions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" namespace="System.Web.UI.WebControls" tagprefix="asp" %>

Okay, at this point we are running great and the feed lists out like we desired.  Now it is time to hook up those two DataPagers we dropped on the page above and below the ListView control.I set the other pager to the same values and that gives me the paging navigation at the top and bottom of the page.  Both can work on the ListView at the same time.

The first step is to set the property "PagedControlID" to the ID of the control we wish this pager to page the data.  In our case we set it to "ListVIew1".  While there I set the PageSize property to "5".

The next step is to select the type of display you wish for the pager.  You can select one of two default types (using the arrow on the DataPager control in design view to select it our build the list of fields by hand.  Here is what the pager would look like in code:

<asp:DataPager runat="server" PagedControlID="ListView1" PageSize="5">
 <fields><asp:nextpreviouspagerfield ButtonType="Button" ShowFirstPageButton="True" ShowNextPageButton="False" ShowPreviousPageButton="False" /><asp:numericpagerfield />
<asp:nextpreviouspagerfield ButtonType="Button" ShowLastPageButton="True" ShowNextPageButton="False"
ShowPreviousPageButton="False" />
</fields>
</asp:DataPager>

Well, that is pretty much it.  It is not too much work and you can have paged data in a list! 

--- Update ---

After a bit of browsing, I found that the ListView has a number of features, including the ability to use groups giving you a more tiled look (or however you configure it) and edit abilities.   There is more info on this at:

http://blogs.msdn.com/kashif/archive/2007/ 01/30/listview-presentation-slides-and-samples.aspx

The big major drawback to using these controls on a Interent based site is SEO issues.  Since the controls work on postbacks and not url parameters, we are still stuck in the same situation where search engines will not be able to index the pages of data.  Since the DataPage is an individual component though, maybe in the future we will see a SEO DataPager that will add this functionality.

Another issue as is with most ASP.NET default server controls is the size of the ViewState.  Oh well, there are still ways around that!