Tuesday, February 1, 2011

Customize SPMetal Generated Code for SharePoint to LINQ

A common question that has come up with SharePoint 2010 developers. If they are using the SPMetal tool to generate entities (or class definitions) for objects in SharePoint, can they modify the generated code? The first response someone may say is no; that is not possible. The reason being is when you rerun the SPMetal command and then replace the new generated code overtop your existing code, you will lose your changes.

Well there is a solution and is it extremely simple. I actually got the idea from all the coding experiences I had with building customizations into RIA Services with Silverlight. All the SPMetal tool is doing is generating Proxy code and notice that all of the code is generated as partial classes!!! Now the sky is the limit.

So in the example below, here is a custom content type I created called Anonymous Comment. Below is the generated code and you can see it is a partial class. Now all you need to do is add another partial class to your project called, AnonymousComment and add in custom methods. When you use the AnonymousComment class in some other custom code it will be treated as one class definition.

Another neat thing you can is see there are partial methods for OnLoaded, OnValidate and OnCreated. You can extend those methods if you want and they will be called by the framework. One unfortunate thing you cannot do is modify the behavior of the getter and setter properties, but you can handle that in your custom partial class.

/// <summary>
/// The item that will capture an anonymous comment.
/// </summary>
[Microsoft.SharePoint.Linq.ContentTypeAttribute(Name="Anonymous Comment", Id="0x0100E3A8FCEBECB140D2812D4F3DE177EFEC")]
public partial class AnonymousComment : Item {

private string _comment;

private System.Nullable<System.DateTime> _created;

private string _response;

private System.Nullable<System.DateTime> _responseDate;

private System.Nullable<Category0> _category;

private System.Nullable<Status> _status;

#region Extensibility Method Definitions
partial void OnLoaded();
partial void OnValidate();
partial void OnCreated();
#endregion

public AnonymousComment() {
this.OnCreated();
}

[Microsoft.SharePoint.Linq.ColumnAttribute(Name="AnonymousComment", Storage="_comment", FieldType="Note")]
public string Comment {
get {
return this._comment;
}
set {
if ((value != this._comment)) {
this.OnPropertyChanging("Comment", this._comment);
this._comment = value;
this.OnPropertyChanged("Comment");
}
}
}

[Microsoft.SharePoint.Linq.ColumnAttribute(Name="Created", Storage="_created", ReadOnly=true, FieldType="DateTime")]
public System.Nullable<System.DateTime> Created {
get {
return this._created;
}
set {
if ((value != this._created)) {
this.OnPropertyChanging("Created", this._created);
this._created = value;
this.OnPropertyChanged("Created");
}
}
}

[Microsoft.SharePoint.Linq.ColumnAttribute(Name="AnonymousCommentResponse", Storage="_response", FieldType="Note")]
public string Response {
get {
return this._response;
}
set {
if ((value != this._response)) {
this.OnPropertyChanging("Response", this._response);
this._response = value;
this.OnPropertyChanged("Response");
}
}
}

[Microsoft.SharePoint.Linq.ColumnAttribute(Name="AnonymousCommentResponseDate", Storage="_responseDate", FieldType="DateTime")]
public System.Nullable<System.DateTime> ResponseDate {
get {
return this._responseDate;
}
set {
if ((value != this._responseDate)) {
this.OnPropertyChanging("ResponseDate", this._responseDate);
this._responseDate = value;
this.OnPropertyChanged("ResponseDate");
}
}
}

[Microsoft.SharePoint.Linq.ColumnAttribute(Name="AnonymousCommentCategory", Storage="_category", FieldType="Choice")]
public System.Nullable<Category0> Category {
get {
return this._category;
}
set {
if ((value != this._category)) {
this.OnPropertyChanging("Category", this._category);
this._category = value;
this.OnPropertyChanged("Category");
}
}
}

[Microsoft.SharePoint.Linq.ColumnAttribute(Name="AnonymousCommentStatus", Storage="_status", FieldType="Choice")]
public System.Nullable<Status> Status {
get {
return this._status;
}
set {
if ((value != this._status)) {
this.OnPropertyChanging("Status", this._status);
this._status = value;
this.OnPropertyChanged("Status");
}
}
}
}

SharePoint 2010 Server Topology Examples

I figured I write a short blog about SharePoint, logical / physical architecture, YET AGAIN!!!

Well I actually received some advice that made me want to tweak my message a little. If you read my earlier blog series on SharePoint 2010 Service architecture you will know how much SharePoint 2010 has changed. Then you may have also read my series on the new SharePoint 2010 Search architecture and found out there have been tons of interesting changes here too.

I had a great presentation from Shane Young (SharePoint MVP) which drove me to write this blog. What I realized is I have to stop thinking about architecting in SharePoint 2007 and take advantage of SharePoint 2010. Heck I should know them given all the new architecture features I have been writing about all this time.

In many SharePoint 2007 implementations, the one service we had much of our planning around was SharePoint Search and the SSP. Now all of those limitations are gone.

I am commonly asked how many servers I need to get started with SharePoint 2010. Now that is a LOADED question because such things as SQL high availability, network, service utilization, enterprise features, etc. which all play into an optimum configuration of SharePoint 2010. There really is no one size fit all. However there is always a good place to start the discussion. Shane Young provided two recommendations which I liked the best.

The Three Server Farm

This one is pretty fun one when you think about. There are a ton of SharePoint 2007 environments out there where there are 3 SharePoint servers and with dedicated SQL Servers. In those cases there are two web front ends and one application server. The one application server runs the index service, maybe something like Excel and the search query services are running on the web front ends. In the SharePoint 2007 days, this gave some good redundancy but with SharePoint 2010 we can do better.

Now one approach you can consider in SharePoint 2010 is just making all three servers the same. Rather novel idea right?

clip_image001

Observations:

  • You now have web traffic distributed across three web front ends.
  • All three servers can support SharePoint 2010 services traffic such as Excel, Visio, Access, etc.
  • Search crawler service should be pretty spiffy because you can configure all three servers to perform full crawling during off hours, and partial crawls depending on how fresh you need to keep search.
  • All three servers can be made redundant from a search perspective by having index mirrors.
  • Search results will actually be quicker because you will have three index partitions that can be searched across simultaneously.

Now I had a colleague point out that this does not fly well because “this does not maximize the separation of services architecture from the web front ends”. I get and completely understand that standpoint but I really do not think that should be a consideration for disqualifying this option. Even though everything is running on each machine, the SharePoint roles / services will continue to run independently in different IIS websites, in separate application pools and with different accounts. There is no reason why you cannot continue to configure it as it if they are running on different machines. This is probably a good thing too because someday you will have to scale SharePoint up to meet demand. Remember you can always scale up by adding boxes or separating services onto their own dedicated machines. All I can say is configure SharePoint 2010 based on your requirements, adhere to best practices, plan as much as you can and do the right configuration for your company.

The Four Server Farm

Now let’s look at a four server SharePoint farm. There will be cases where the three server farm recommendation will not make sense for whatever the valid reason. In this configuration we go a little more “traditional”. In this case, Shane recommend two web front ends and then two application servers.

clip_image002

Observations:

  • We have two dedicated web front ends. Add more if you need to.
  • Application services will run on the same application servers with search. Hopefully they will not interfere with full crawls unless you require dedicated resources for the application services. If you need; just add more application servers.
  • The two application servers give us the needed redundancy we need for search. You will have two crawlers and two index partitions with mirrors to start with.
  • One little trick I was told for this configuration is you should also configure the application servers where the Search crawling component is running to also be web front ends (WFE). Do not load balance them with the other WFEs. Then add the SharePoint site URLs to be searched as entries into the hosts file on the application servers to point back to itself and not to the load balanced URL. What this effectively does is trick the crawler into crawling the WFE on the application server. This will give performance improvements twofold. First the load balanced WFEs where users access content will have no performance issues associated to the crawler crawling content. Second, the load of the network will be reduced because nothing will go across the wire when indexing is occurring.

Additional Notes:

  • High Availability – SQL is a big player in this discussion and you need to read this blog.
  • FAST for SharePoint 2010 - Now if you are going to consider using FAST for SharePoint, I would probably vote for the three server architecture recommendation as a starting off point. Here is a blog series on FAST for SharePoint 2010 if you are interested.

Closing

As I have said, there is no one size fits all. This is just a place to start and based on your plans you will scale up the SharePoint 2010 architecture as needed.

SharePoint 2010 Health Analyzer and RSS Feeds

In Central Admin of SharePoint 2010 you are probably familiar with the Health Analyzer. It was around in SharePoint 2007. Now in SharePoint 2010 – you see a ribbon right on the central admin homepage.

clip_image002

So a colleague and I were joking around that why not put an RSS feed in Outlook against the list that stores health errors so you can get automatic notification of when there is a Health Issue.

Guess what, not that bad of an idea. Now I will get notification if one of my rules fail in production. This is not a replacement for SCOM, but just something simple you can do to monitor your SharePoint Health Analyzer rules. Now I know many folks could debate some of the rules but at the end of the day most of them are good best practices you may want to adhere to in a production environment.

clip_image004

Health Analyzer Rules

If you are not familiar with the Health Analyzer rules, they can be managed in Central Admin. Below is screenshot of some of the actual rule definitions.

clip_image006

Here is an actual rule definition. You can see there is a schedule to when the rule is evaluated. Also notice there is a Run Now button which will execute rule manually. You even have the ability to disable rules which do not apply to your governance rules so that they will not continually appear in your RSS feed.

clip_image008