<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://customerfx.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">Ryan Farley&amp;#39;s Blog</title><subtitle type="html">Ryan Farley on .NET Development with a focus on CRM Development for SalesLogix</subtitle><id>http://customerfx.com/pages/crmdeveloper/atom.aspx</id><link rel="alternate" type="text/html" href="http://customerfx.com/pages/crmdeveloper/default.aspx" /><link rel="self" type="application/atom+xml" href="http://customerfx.com/pages/crmdeveloper/atom.aspx" /><generator uri="http://communityserver.org" version="3.0.20611.960">Community Server</generator><updated>2009-01-30T15:34:00Z</updated><entry><title>A Look at Querying Data in SalesLogix using IRepository and the SQL Equivalents</title><link rel="alternate" type="text/html" href="http://customerfx.com/pages/crmdeveloper/2010/03/05/a-look-at-querying-data-in-saleslogix-using-irepository-and-the-sql-equivalents.aspx" /><id>http://customerfx.com/pages/crmdeveloper/2010/03/05/a-look-at-querying-data-in-saleslogix-using-irepository-and-the-sql-equivalents.aspx</id><published>2010-03-05T18:17:00Z</published><updated>2010-03-05T18:17:00Z</updated><content type="html">&lt;p&gt;For some who have been working in the SalesLogix LAN client for years, the transition from using SQL queries to retrieving data using a repository with the entity model can be a difficult change. This post will look at some common data retrieval methods and the SQL equivalents to help you get your head around how to get work done using the entity model.&lt;/p&gt;
&lt;p&gt;&lt;font size="4"&gt;&lt;b&gt;&lt;br /&gt;Retrieving All Records from a Table&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;The following is an example query to retrieve all records in a table.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;SQL Equivalent&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;span style="color:Blue;"&gt;SELECT&lt;/span&gt; * &lt;span style="color:Blue;"&gt;FROM&lt;/span&gt; PRODUCT&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;&lt;b&gt;Code&lt;/b&gt;&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;Sage.Platform.Repository.IRepository&amp;lt;Sage.Entity.Interfaces.IProduct&amp;gt; repository &lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;br /&gt;    Sage.Platform.EntityFactory.GetRepository&amp;lt;Sage.Entity.Interfaces.IProduct&amp;gt;();&lt;br /&gt;     &lt;br /&gt;&lt;span style="color:Green;"&gt;// returns an IList&amp;lt;IProduct&amp;gt;&lt;br /&gt;&lt;/span&gt;result &lt;span style="color:Navy;"&gt;=&lt;/span&gt; repository.FindAll();&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;






&lt;p&gt;&lt;font size="4"&gt;&lt;b&gt;&lt;br /&gt;Sorting Query Results&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;The following will retrieve all records from a table and sort the results.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;SQL Equivalent&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;span style="color:Blue;"&gt;SELECT&lt;/span&gt; * &lt;span style="color:Blue;"&gt;FROM&lt;/span&gt; PRODUCT &lt;span style="color:Blue;"&gt;ORDER&lt;/span&gt; &lt;span style="color:Blue;"&gt;BY&lt;/span&gt; FAMILY &lt;span style="color:Blue;"&gt;ASC&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;&lt;b&gt;Code&lt;/b&gt;&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;Sage.Platform.Repository.IRepository&amp;lt;Sage.Entity.Interfaces.IProduct&amp;gt; repository &lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;br /&gt;    Sage.Platform.EntityFactory.GetRepository&amp;lt;Sage.Entity.Interfaces.IProduct&amp;gt;();&lt;br /&gt; &lt;br /&gt;&lt;span style="color:Green;"&gt;// setup the query&lt;br /&gt;&lt;/span&gt;IQueryable query &lt;span style="color:Navy;"&gt;=&lt;/span&gt; (IQueryable)repository;&lt;br /&gt; &lt;br /&gt;&lt;span style="color:Green;"&gt;// setup the expression factory&lt;br /&gt;&lt;/span&gt;IExpressionFactory ef &lt;span style="color:Navy;"&gt;=&lt;/span&gt; query.GetExpressionFactory();&lt;br /&gt; &lt;br /&gt;&lt;span style="color:Green;"&gt;// setup your criteria &lt;br /&gt;&lt;/span&gt;ICriteria criteria &lt;span style="color:Navy;"&gt;=&lt;/span&gt; query.CreateCriteria();&lt;br /&gt; &lt;br /&gt;&lt;span style="color:Green;"&gt;// add sort order&lt;br /&gt;&lt;/span&gt;criteria.AddOrder(ef.Asc(&lt;span&gt;&amp;quot;Family&amp;quot;&lt;/span&gt;));&lt;br /&gt; &lt;br /&gt;&lt;span style="color:Green;"&gt;// returns an IList&amp;lt;IProduct&amp;gt;&lt;br /&gt;&lt;/span&gt;result &lt;span style="color:Navy;"&gt;=&lt;/span&gt; criteria.List&amp;lt;IProduct&amp;gt;();&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;





&lt;p&gt;&lt;font size="4"&gt;&lt;b&gt;&lt;br /&gt;Query Using Where - Finding All Opportunities for an Account&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;The following will add a condition to a query to retrieve all opportunities for an account and order results.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;SQL Equivalent&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;span style="color:Blue;"&gt;SELECT&lt;/span&gt; * &lt;span style="color:Blue;"&gt;FROM&lt;/span&gt; OPPORTUNITY &lt;span style="color:Blue;"&gt;WHERE&lt;/span&gt; ACCOUNTID = &lt;span style="color:Navy;"&gt;&amp;#39;SOMEACCOUNTID&amp;#39;&lt;/span&gt; &lt;span style="color:Blue;"&gt;ORDER&lt;/span&gt; &lt;span style="color:Blue;"&gt;BY&lt;/span&gt; DESCRIPTION &lt;span style="color:Blue;"&gt;ASC&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;&lt;b&gt;Code&lt;/b&gt;&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;span style="color:Green;"&gt;// Using repository helper&lt;br /&gt;&lt;/span&gt;Sage.Platform.RepositoryHelper&amp;lt;Sage.Entity.Interfaces.IOpportunity&amp;gt; repository &lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;br /&gt;    Sage.Platform.EntityFactory.GetRepositoryHelper&amp;lt;Sage.Entity.Interfaces.IOpportunity&amp;gt;();&lt;br /&gt; &lt;br /&gt;&lt;span style="color:Green;"&gt;// EF and PF are setup automatically&lt;br /&gt;&lt;/span&gt; &lt;br /&gt;&lt;span style="color:Green;"&gt;// setup your criteria &lt;br /&gt;&lt;/span&gt;ICriteria criteria &lt;span style="color:Navy;"&gt;=&lt;/span&gt; repository.CreateCriteria();&lt;br /&gt; &lt;br /&gt;&lt;span style="color:Green;"&gt;// add condition for account&lt;br /&gt;&lt;/span&gt;criteria.Add(repository.EF.Eq(&lt;span&gt;&amp;quot;Account&amp;quot;&lt;/span&gt;, account));&lt;br /&gt; &lt;br /&gt;&lt;span style="color:Green;"&gt;// add sort order&lt;br /&gt;&lt;/span&gt;criteria.AddOrder(ef.Asc(&lt;span&gt;&amp;quot;Description&amp;quot;&lt;/span&gt;));&lt;br /&gt; &lt;br /&gt;&lt;span style="color:Green;"&gt;// returns an IList&amp;lt;IOpportunity&amp;gt;&lt;br /&gt;&lt;/span&gt;result &lt;span style="color:Navy;"&gt;=&lt;/span&gt; criteria.List&amp;lt;IOpportunity&amp;gt;();&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;





&lt;p&gt;&lt;font size="4"&gt;&lt;b&gt;&lt;br /&gt;Query Conditions using AND&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;The following will AND several query conditions together and order the results.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;SQL Equivalent&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;span style="color:Blue;"&gt;SELECT&lt;/span&gt; * &lt;span style="color:Blue;"&gt;FROM&lt;/span&gt; OPPORTUNITY &lt;span style="color:Blue;"&gt;WHERE&lt;/span&gt; STATUS = &lt;span style="color:Navy;"&gt;&amp;#39;Closed - Won&amp;#39;&lt;/span&gt; &lt;span style="color:Blue;"&gt;AND&lt;/span&gt; DESCRIPTION = &lt;span style="color:Navy;"&gt;&amp;#39;Some Description&amp;#39;&lt;/span&gt; &lt;span style="color:Blue;"&gt;ORDER&lt;/span&gt; &lt;span style="color:Blue;"&gt;BY&lt;/span&gt; DESCRIPTION &lt;span style="color:Blue;"&gt;ASC&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;&lt;b&gt;Code&lt;/b&gt;&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;span style="color:Green;"&gt;// Using repository helper&lt;br /&gt;&lt;/span&gt;Sage.Platform.RepositoryHelper&amp;lt;Sage.Entity.Interfaces.IOpportunity&amp;gt; repository &lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;br /&gt;    Sage.Platform.EntityFactory.GetRepositoryHelper&amp;lt;Sage.Entity.Interfaces.IOpportunity&amp;gt;();&lt;br /&gt; &lt;br /&gt;&lt;span style="color:Green;"&gt;// EF and PF are setup automatically&lt;br /&gt;&lt;/span&gt; &lt;br /&gt;&lt;span style="color:Green;"&gt;// setup your criteria &lt;br /&gt;&lt;/span&gt;ICriteria criteria &lt;span style="color:Navy;"&gt;=&lt;/span&gt; repository.CreateCriteria();&lt;br /&gt; &lt;br /&gt;&lt;span style="color:Green;"&gt;// AND conditions together&lt;br /&gt;&lt;/span&gt;criteria.Add(repository.EF.Conjunction()&lt;br /&gt;    .Add(repository.EF.Eq(&lt;span&gt;&amp;quot;Status&amp;quot;&lt;/span&gt;, &lt;span&gt;&amp;quot;Closed - Won&amp;quot;&lt;/span&gt;))&lt;br /&gt;    .Add(repository.EF.Eq(&lt;span&gt;&amp;quot;Description&amp;quot;&lt;/span&gt;, &lt;span&gt;&amp;quot;Some Description&amp;quot;&lt;/span&gt;));&lt;br /&gt; &lt;br /&gt;&lt;span style="color:Green;"&gt;// add sort order&lt;br /&gt;&lt;/span&gt;criteria.AddOrder(ef.Asc(&lt;span&gt;&amp;quot;Description&amp;quot;&lt;/span&gt;));&lt;br /&gt; &lt;br /&gt;&lt;span style="color:Green;"&gt;// returns an IList&amp;lt;IOpportunity&amp;gt;&lt;br /&gt;&lt;/span&gt;result &lt;span style="color:Navy;"&gt;=&lt;/span&gt; criteria.List&amp;lt;IOpportunity&amp;gt;();&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;





&lt;p&gt;&lt;font size="4"&gt;&lt;b&gt;&lt;br /&gt;Query Conditions using OR&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;The following will OR several query conditions together and order the results.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;SQL Equivalent&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;span style="color:Blue;"&gt;SELECT&lt;/span&gt; * &lt;span style="color:Blue;"&gt;FROM&lt;/span&gt; OPPORTUNITY &lt;span style="color:Blue;"&gt;WHERE&lt;/span&gt; STATUS = &lt;span style="color:Navy;"&gt;&amp;#39;Closed - Won&amp;#39;&lt;/span&gt; &lt;span style="color:Blue;"&gt;OR&lt;/span&gt; STATUS = &lt;span style="color:Navy;"&gt;&amp;#39;Open&amp;#39;&lt;/span&gt; &lt;span style="color:Blue;"&gt;ORDER&lt;/span&gt; &lt;span style="color:Blue;"&gt;BY&lt;/span&gt; DESCRIPTION &lt;span style="color:Blue;"&gt;ASC&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;&lt;b&gt;Code&lt;/b&gt;&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;span style="color:Green;"&gt;// Using repository helper (EF and PF are setup automatically)&lt;br /&gt;&lt;/span&gt;Sage.Platform.RepositoryHelper&amp;lt;Sage.Entity.Interfaces.IOpportunity&amp;gt; repository &lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;br /&gt;    Sage.Platform.EntityFactory.GetRepositoryHelper&amp;lt;Sage.Entity.Interfaces.IOpportunity&amp;gt;();&lt;br /&gt; &lt;br /&gt;&lt;span style="color:Green;"&gt;// setup your criteria &lt;br /&gt;&lt;/span&gt;ICriteria criteria &lt;span style="color:Navy;"&gt;=&lt;/span&gt; repository.CreateCriteria();&lt;br /&gt; &lt;br /&gt;&lt;span style="color:Green;"&gt;// OR conditions together&lt;br /&gt;&lt;/span&gt;criteria.Add(repository.EF.Or(repository.EF.Eq(&lt;span&gt;&amp;quot;Status&amp;quot;&lt;/span&gt;, &lt;span&gt;&amp;quot;Closed - Won&amp;quot;&lt;/span&gt;), &lt;br /&gt;                              repository.EF.Eq(&lt;span&gt;&amp;quot;Status&amp;quot;&lt;/span&gt;, &lt;span&gt;&amp;quot;Open&amp;quot;&lt;/span&gt;)));&lt;br /&gt; &lt;br /&gt;&lt;span style="color:Green;"&gt;// add sort order&lt;br /&gt;&lt;/span&gt;criteria.AddOrder(ef.Asc(&lt;span&gt;&amp;quot;Description&amp;quot;&lt;/span&gt;));&lt;br /&gt; &lt;br /&gt;&lt;span style="color:Green;"&gt;// returns an IList&amp;lt;IOpportunity&amp;gt;&lt;br /&gt;&lt;/span&gt;result &lt;span style="color:Navy;"&gt;=&lt;/span&gt; criteria.List&amp;lt;IOpportunity&amp;gt;();&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;





&lt;p&gt;&lt;font size="4"&gt;&lt;b&gt;&lt;br /&gt;Query Conditions using IN&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;The following will IN several query conditions together and order the results.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;SQL Equivalent&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;span style="color:Blue;"&gt;SELECT&lt;/span&gt; * &lt;span style="color:Blue;"&gt;FROM&lt;/span&gt; OPPORTUNITY &lt;span style="color:Blue;"&gt;WHERE&lt;/span&gt; STATUS &lt;span style="color:Blue;"&gt;IN&lt;/span&gt; (&lt;span style="color:Navy;"&gt;&amp;#39;Closed - Won&amp;#39;&lt;/span&gt;,&lt;span style="color:Navy;"&gt;&amp;#39;Open&amp;#39;&lt;/span&gt;,&lt;span style="color:Navy;"&gt;&amp;#39;Closed - Lost&amp;#39;&lt;/span&gt;) &lt;span style="color:Blue;"&gt;ORDER&lt;/span&gt; &lt;span style="color:Blue;"&gt;BY&lt;/span&gt; DESCRIPTION &lt;span style="color:Blue;"&gt;ASC&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;&lt;b&gt;Code&lt;/b&gt;&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;span style="color:Green;"&gt;// Using repository helper (EF and PF are setup automatically)&lt;br /&gt;&lt;/span&gt;Sage.Platform.RepositoryHelper&amp;lt;Sage.Entity.Interfaces.IOpportunity&amp;gt; repository &lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;br /&gt;    Sage.Platform.EntityFactory.GetRepositoryHelper&amp;lt;Sage.Entity.Interfaces.IOpportunity&amp;gt;();&lt;br /&gt; &lt;br /&gt;&lt;span style="color:Green;"&gt;// setup your criteria &lt;br /&gt;&lt;/span&gt;ICriteria criteria &lt;span style="color:Navy;"&gt;=&lt;/span&gt; repository.CreateCriteria();&lt;br /&gt; &lt;br /&gt;&lt;span style="color:Green;"&gt;// IN conditions together&lt;br /&gt;&lt;/span&gt;criteria.Add(repository.EF.In(&lt;span&gt;&amp;quot;Status&amp;quot;&lt;/span&gt;, &lt;span style="color:Blue;"&gt;new&lt;/span&gt; &lt;span style="color:Blue;"&gt;string&lt;/span&gt;[] {&lt;span&gt;&amp;quot;Closed - Won&amp;quot;&lt;/span&gt;, &lt;span&gt;&amp;quot;Open&amp;quot;&lt;/span&gt;, &lt;span&gt;&amp;quot;Closed - Lost&amp;quot;&lt;/span&gt;})); &lt;br /&gt; &lt;br /&gt;&lt;span style="color:Green;"&gt;// add sort order&lt;br /&gt;&lt;/span&gt;criteria.AddOrder(ef.Asc(&lt;span&gt;&amp;quot;Description&amp;quot;&lt;/span&gt;));&lt;br /&gt; &lt;br /&gt;&lt;span style="color:Green;"&gt;// returns an IList&amp;lt;IOpportunity&amp;gt;&lt;br /&gt;&lt;/span&gt;result &lt;span style="color:Navy;"&gt;=&lt;/span&gt; criteria.List&amp;lt;IOpportunity&amp;gt;();&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;





&lt;p&gt;&lt;font size="4"&gt;&lt;b&gt;&lt;br /&gt;Query Conditions using BETWEEN&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;The following will BETWEEN several query conditions together and order the results.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;SQL Equivalent&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;span style="color:Blue;"&gt;SELECT&lt;/span&gt; * &lt;span style="color:Blue;"&gt;FROM&lt;/span&gt; OPPORTUNITY &lt;span style="color:Blue;"&gt;WHERE&lt;/span&gt; STATUS &lt;span style="color:Blue;"&gt;BETWEEN&lt;/span&gt; 50000 &lt;span style="color:Blue;"&gt;AND&lt;/span&gt; 150000 &lt;span style="color:Blue;"&gt;ORDER&lt;/span&gt; &lt;span style="color:Blue;"&gt;BY&lt;/span&gt; DESCRIPTION &lt;span style="color:Blue;"&gt;ASC&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;&lt;b&gt;Code&lt;/b&gt;&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;span style="color:Green;"&gt;// Using repository helper (EF and PF are setup automatically)&lt;br /&gt;&lt;/span&gt;Sage.Platform.RepositoryHelper&amp;lt;Sage.Entity.Interfaces.IOpportunity&amp;gt; repository &lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;br /&gt;    Sage.Platform.EntityFactory.GetRepositoryHelper&amp;lt;Sage.Entity.Interfaces.IOpportunity&amp;gt;();&lt;br /&gt; &lt;br /&gt;&lt;span style="color:Green;"&gt;// setup your criteria &lt;br /&gt;&lt;/span&gt;ICriteria criteria &lt;span style="color:Navy;"&gt;=&lt;/span&gt; repository.CreateCriteria();&lt;br /&gt; &lt;br /&gt;&lt;span style="color:Green;"&gt;// BETWEEN conditions together&lt;br /&gt;&lt;/span&gt;criteria.Add(repository.EF.Between(&lt;span&gt;&amp;quot;SalesPotential&amp;quot;&lt;/span&gt;, 50000, 150000)); &lt;br /&gt; &lt;br /&gt;&lt;span style="color:Green;"&gt;// add sort order&lt;br /&gt;&lt;/span&gt;criteria.AddOrder(ef.Asc(&lt;span&gt;&amp;quot;Description&amp;quot;&lt;/span&gt;));&lt;br /&gt; &lt;br /&gt;&lt;span style="color:Green;"&gt;// returns an IList&amp;lt;IOpportunity&amp;gt;&lt;br /&gt;&lt;/span&gt;result &lt;span style="color:Navy;"&gt;=&lt;/span&gt; criteria.List&amp;lt;IOpportunity&amp;gt;();&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;





&lt;p&gt;&lt;font size="4"&gt;&lt;b&gt;&lt;br /&gt;Query Conditions using LIKE&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;The following will LIKE a query condition and order the results.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;SQL Equivalent&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;span style="color:Blue;"&gt;SELECT&lt;/span&gt; * &lt;span style="color:Blue;"&gt;FROM&lt;/span&gt; OPPORTUNITY &lt;span style="color:Blue;"&gt;WHERE&lt;/span&gt; STATUS &lt;span style="color:Blue;"&gt;LIKE&lt;/span&gt; &lt;span style="color:Navy;"&gt;&amp;#39;Closed%&amp;#39;&lt;/span&gt; &lt;span style="color:Blue;"&gt;ORDER&lt;/span&gt; &lt;span style="color:Blue;"&gt;BY&lt;/span&gt; DESCRIPTION &lt;span style="color:Blue;"&gt;ASC&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;&lt;b&gt;Code&lt;/b&gt;&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;span style="color:Green;"&gt;// Using repository helper (EF and PF are setup automatically)&lt;br /&gt;&lt;/span&gt;Sage.Platform.RepositoryHelper&amp;lt;Sage.Entity.Interfaces.IOpportunity&amp;gt; repository &lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;br /&gt;    Sage.Platform.EntityFactory.GetRepositoryHelper&amp;lt;Sage.Entity.Interfaces.IOpportunity&amp;gt;();&lt;br /&gt; &lt;br /&gt;&lt;span style="color:Green;"&gt;// setup your criteria &lt;br /&gt;&lt;/span&gt;ICriteria criteria &lt;span style="color:Navy;"&gt;=&lt;/span&gt; repository.CreateCriteria();&lt;br /&gt; &lt;br /&gt;&lt;span style="color:Green;"&gt;// LIKE conditions together&lt;br /&gt;&lt;/span&gt;criteria.Add(repository.EF.Like(&lt;span&gt;&amp;quot;Status&amp;quot;&lt;/span&gt;, &lt;span&gt;&amp;quot;Closed%&amp;quot;&lt;/span&gt;)); &lt;br /&gt; &lt;br /&gt;&lt;span style="color:Green;"&gt;// add sort order&lt;br /&gt;&lt;/span&gt;criteria.AddOrder(ef.Asc(&lt;span&gt;&amp;quot;Description&amp;quot;&lt;/span&gt;));&lt;br /&gt; &lt;br /&gt;&lt;span style="color:Green;"&gt;// returns an IList&amp;lt;IOpportunity&amp;gt;&lt;br /&gt;&lt;/span&gt;result &lt;span style="color:Navy;"&gt;=&lt;/span&gt; criteria.List&amp;lt;IOpportunity&amp;gt;();&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;&lt;br /&gt;Hopefully that helps make the transition a bit easier. On this same topic, don&amp;#39;t forget to check out &lt;a href="http://customerfx.com/pages/integrationblog/2010/03/04/using-icriteria-and-not-to-exclude-records-in-saleslogix.aspx"&gt;Kris Halsrud&amp;#39;s post on using NOT to exclude conditions&lt;/a&gt;.&amp;nbsp; &lt;br /&gt;&lt;/p&gt;


&lt;img src="http://customerfx.com/aggbug.aspx?PostID=41520" width="1" height="1"&gt;</content><author><name>Ryan Farley</name><uri>http://customerfx.com/members/Ryan-Farley.aspx</uri></author><category term="Development" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Development/default.aspx" /><category term="SalesLogix Web" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/SalesLogix+Web/default.aspx" /><category term="SalesLogix" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/SalesLogix/default.aspx" /><category term="Entity Model" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Entity+Model/default.aspx" /><category term="Query" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Query/default.aspx" /><category term="IRepository" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/IRepository/default.aspx" /></entry><entry><title>Community Explorer - The Desktop Client for the Sage SalesLogix Community Forums</title><link rel="alternate" type="text/html" href="http://customerfx.com/pages/crmdeveloper/2010/02/09/community-explorer-the-desktop-client-for-the-sage-saleslogix-community-forums.aspx" /><id>http://customerfx.com/pages/crmdeveloper/2010/02/09/community-explorer-the-desktop-client-for-the-sage-saleslogix-community-forums.aspx</id><published>2010-02-09T23:25:00Z</published><updated>2010-02-09T23:25:00Z</updated><content type="html">&lt;p&gt;Ever since Sage released their official SalesLogix community website &amp;amp; forums, I&amp;#39;ve wanted a better way to search and browse the forums. I&amp;#39;ve been working on a desktop client that does just this in a better, faster, and more efficient way. So, I&amp;#39;d like to announce the public release of &lt;b&gt;Community Explorer&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;&lt;a href="http://customerfx.com/blogs/cfxproducts/CommunityExplorer/CommunityExplorer_Search.png"&gt;&lt;img src="http://customerfx.com/blogs/cfxproducts/CommunityExplorer/CommunityExplorer_Search-Smaller.png" border="0" alt="" /&gt;&lt;/a&gt; &lt;br /&gt;&lt;font color="gray"&gt;&lt;i&gt;&amp;nbsp; (click to view larger image)&lt;/i&gt;&lt;/font&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Community Explorer is a desktop application that will allow you to search the official Sage SalesLogix community forums and blogs in a much faster, precise, and effective way - letting you get to the information you need faster. It also allows you to simply browse the community forums in an easier way, similar to browsing a newsgroup or e-mail.&lt;/p&gt;&lt;p&gt;The current version is beta, so expect to see releases with bug fixes. There are also more features planned for Community Explorer, including viewing recent posts &amp;amp; threads and even toast-like desktop notifications alerting you of new activity in the forums.&lt;/p&gt;&lt;p&gt;Take a look at the &lt;a href="http://customerfx.com/pages/cfxproducts/1999/01/01/community-explorer.aspx"&gt;Community Explorer page&lt;/a&gt; and install it to give it a try. I would love to hear your feedback! &lt;br /&gt;&lt;/p&gt;&lt;img src="http://customerfx.com/aggbug.aspx?PostID=41475" width="1" height="1"&gt;</content><author><name>Ryan Farley</name><uri>http://customerfx.com/members/Ryan-Farley.aspx</uri></author><category term="General" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/General/default.aspx" /><category term="SalesLogix" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/SalesLogix/default.aspx" /><category term="Beta" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Beta/default.aspx" /><category term="Community Explorer" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Community+Explorer/default.aspx" /></entry><entry><title>Big Update for Git Extensions for SalesLogix - Now Automatically Updates and Installer Available</title><link rel="alternate" type="text/html" href="http://customerfx.com/pages/crmdeveloper/2009/12/22/big-update-for-git-extensions-for-saleslogix-now-automatically-updates-and-installer-available.aspx" /><id>http://customerfx.com/pages/crmdeveloper/2009/12/22/big-update-for-git-extensions-for-saleslogix-now-automatically-updates-and-installer-available.aspx</id><published>2009-12-22T17:50:00Z</published><updated>2009-12-22T17:50:00Z</updated><content type="html">&lt;p&gt;&lt;img src="http://customerfx.com/blogs/crmdeveloper/logo.png" border="0" alt="" /&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;I have released a big update for Git Extensions for SalesLogix. This new version includes a ClickOnce installer and will keep itself up to date automatically. The installation of Git Extensions for SalesLogix is now brain-dead easy. You just access a URL and click the Install button. Not only that, you&amp;#39;ll automagically be updated to new releases as they become available. I&amp;#39;ve recorded a quick video to show how these new features work.&lt;/p&gt;

&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://www.screencast.com/t/NGE2ZTJl" target="_blank" title="Watch the Git Extensions for SalesLogix Installer Video"&gt;&lt;img src="http://customerfx.com/blogs/crmdeveloper/play.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/td&gt;

&lt;td&gt;&lt;font size="3"&gt;&lt;b&gt;&lt;a href="http://www.screencast.com/t/NGE2ZTJl" target="_blank" title="Watch the Git Extensions for SalesLogix Installer Video"&gt;Watch the Git Extensions for SalesLogix Installer Preview Video&lt;/a&gt;&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#404040"&gt;&lt;i&gt;The video will open on screencast.com in a new window&lt;/i&gt;&lt;/font&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;&lt;br /&gt;This update will make things great moving forward since you&amp;#39;ll automatically get new updates without any effort at all. One important part of this release is that the SalesLogix.xml file is no longer updated at all. The Git Extensions for SalesLogix assembly gets loaded into Application Architect without any configuration changes at all. This will avoid the problem with Sage updates not updating the SalesLogix.xml file because it was modified. Kris described this problem &lt;a href="http://customerfx.com/pages/integrationblog/2009/12/15/unable-to-open-7-5-2-application-architect-after-upgrading-from-7-5-1.aspx"&gt;here&lt;/a&gt;. This problem will no longer exist since the XML file is never touched with the new version.&lt;/p&gt;

&lt;p&gt;The installer is a ClickOnce application. You&amp;#39;ll just go to the install URL and a wizard will start:&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://customerfx.com/blogs/crmdeveloper/GitExtensionsInstaller.png"&gt;&lt;img src="http://customerfx.com/blogs/crmdeveloper/GitExtensionsInstaller.png" border="0" alt="" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;font size="4"&gt;&lt;span style="font-weight:bold;"&gt;Install Git Extensions for SalesLogix&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;To install Git Extensions for SalesLogix you must remove any previous versions. This is only a requirement this time only. From now on things will self-update. However, if you&amp;#39;ve had an earlier version installed, this is very important. See the full details to install Git Extensions for SalesLogix, or for instructions to remove an earlier version, visit the project Wiki on Github&lt;/p&gt;

&lt;div style="margin-left:40px;"&gt;&lt;img src="http://customerfx.com/themes/customerfx/images/custom/install_24x24.png" align="absmiddle" alt="" /&gt; &lt;font size="3"&gt;&lt;a href="http://wiki.github.com/CustomerFX/SalesLogixGitExtensions/installation" style="font-weight:bold;" target="_blank"&gt;Install Git Extensions for SalesLogix&lt;/a&gt;&lt;/font&gt;&lt;/div&gt;

&lt;p&gt;I&amp;#39;d love to hear feedback on how Git Extensions for SalesLogix is working out for you. Personally, I love it. It makes working with source control for a SalesLogix project painless and easy since it is all built right into Application Architect. Remember, all the installer stuff is brand new, so please let me know if you run into any bugs by leaving a comment, or even better yet, &lt;a href="http://github.com/CustomerFX/SalesLogixGitExtensions/issues" target="_blank"&gt;log it as an issue on the project site&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt;
&lt;img src="http://customerfx.com/aggbug.aspx?PostID=41346" width="1" height="1"&gt;</content><author><name>Ryan Farley</name><uri>http://customerfx.com/members/Ryan-Farley.aspx</uri></author><category term="Open Source" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Open+Source/default.aspx" /><category term="Git" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Git/default.aspx" /><category term="Git Extensions for SalesLogix" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Git+Extensions+for+SalesLogix/default.aspx" /></entry><entry><title>Showing a Message to the User from a Code Snippet Action in SalesLogix Web</title><link rel="alternate" type="text/html" href="http://customerfx.com/pages/crmdeveloper/2009/12/10/showing-a-message-to-the-user-from-a-code-snippet-action-in-saleslogix-web.aspx" /><id>http://customerfx.com/pages/crmdeveloper/2009/12/10/showing-a-message-to-the-user-from-a-code-snippet-action-in-saleslogix-web.aspx</id><published>2009-12-10T19:28:00Z</published><updated>2009-12-10T19:28:00Z</updated><content type="html">
&lt;p&gt;Showing a message to a user in SalesLogix Web is an easy task. It should be, right? Of course - and it is, however, you might need to know where to look to do it. This post will take a look at how to do this from both a Code Snippet Action and a C# Snippet Action. &lt;/p&gt;
&lt;p&gt;Showing a message in the web client, like using MsgBox from a LAN client script, requires use of the DialogService. The DialogService has a ShowMessage method you can use to display a message to the user.&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="4"&gt;&lt;b&gt;&lt;br /&gt;From a Code Snippet Action&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;To use the DialogService from a Code Snippet Action, you need to use the form&amp;#39;s WorkItem reference that is passed in to the code action. This will allow you to get access to the DialogService.&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre&gt;&lt;span style="color:Green;"&gt;// Get a reference to the DialogService&lt;br /&gt;&lt;/span&gt;Sage.Platform.WebPortal.Services.IWebDialogService dialogService &lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;br /&gt;        form.WorkItem.Services.Get&amp;lt;Sage.Platform.WebPortal.Services.IWebDialogService&amp;gt;();&lt;br /&gt;&lt;span style="color:Green;"&gt;// Now show a message to the user&lt;br /&gt;&lt;/span&gt;dialogService.ShowMessage(&lt;span&gt;&amp;quot;You must first do something.&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;Easy enough, now let&amp;#39;s take a look at how to do this from a C# Snippet Action.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;font size="4"&gt;&lt;b&gt;From a C# Snippet Action&lt;/b&gt;&lt;/font&gt; &lt;/p&gt;
&lt;p&gt;From a C# Snippet Action things a a little different. &lt;a href="http://customerfx.com/pages/crmdeveloper/2009/03/26/setting-the-default-sort-for-a-datagrid-in-saleslogix-web-revisited.aspx"&gt;As I mentioned before&lt;/a&gt;, code in a C# Snippet Action gets placed directly on the SmartPart (the ASCX UserControl). The code is inline on the deployed ASCX file itself. The SmartPart inherits from EntityBoundSmartPartProvider which eventually inherits from Sage.Platform.WebPortal.SmartParts.SmartPart which has a built-in DialogService reference. What this means is that you no longer have to get a reference to the DialogService yourself, you just use the one you already have.&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;span style="color:Green;"&gt;// Show a message to the user&lt;br /&gt;&lt;/span&gt;&lt;span style="color:Blue;"&gt;this&lt;/span&gt;.DialogService.ShowMessage(&lt;span&gt;&amp;quot;You must first do something.&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;&lt;br /&gt;Either way, whether you&amp;#39;re in a C# Snippet, or the Code Action things are all nice and simple, as it should be.&lt;br /&gt;&lt;/p&gt;
&lt;img src="http://customerfx.com/aggbug.aspx?PostID=41217" width="1" height="1"&gt;</content><author><name>Ryan Farley</name><uri>http://customerfx.com/members/Ryan-Farley.aspx</uri></author><category term="SalesLogix Web" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/SalesLogix+Web/default.aspx" /><category term="C#" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/C_2300_/default.aspx" /><category term="Code Action" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Code+Action/default.aspx" /></entry><entry><title>Account Hierarchy for SalesLogix Web Source Code Has a New Home</title><link rel="alternate" type="text/html" href="http://customerfx.com/pages/crmdeveloper/2009/12/07/account-hierarchy-for-saleslogix-web-source-code-has-a-new-home.aspx" /><id>http://customerfx.com/pages/crmdeveloper/2009/12/07/account-hierarchy-for-saleslogix-web-source-code-has-a-new-home.aspx</id><published>2009-12-07T22:32:00Z</published><updated>2009-12-07T22:32:00Z</updated><content type="html">&lt;p&gt;The &lt;a href="http://customerfx.com/pages/cfxproducts/2000/01/08/account-hierarchy-for-saleslogix-web.aspx"&gt;Account Hierarchy for SalesLogix Web&lt;/a&gt; module has a new home. I have moved the source to Github to make a public repository for the code and make it easier for others to get the latest source as I make changes to it (and hopefully get some contributions from others too who use it).&lt;/p&gt;&lt;p&gt;&lt;a href="http://customerfx.com/blogs/graduates/AccountHierarchy/AccountHierarchy.jpg" target="_blank"&gt;&lt;img src="http://customerfx.com/blogs/graduates/AccountHierarchy/th_AccountHierarchy.jpg" border="0" height="270" width="498" alt="" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I released a public download of the Account Hierarchy module almost a year and a half ago for SalesLogix 7.2. Since that time it has had hundreds of downloads. I have make some tweaks over time and decided there needed to be a better way to share those tweaks. So, the Github repository will be the permanent location for this module going forward. Also, I opted to make the repository for the SmartPart ascx and cs files separate from a full model. This is intentional because I typically will use this in a full model that is already under source control. This way you can just clone the repository and copy the files into your working model as needed. Of course the full bundle will be available as well.&lt;/p&gt;


&lt;table&gt;

&lt;tr&gt;
&lt;td&gt;&lt;img src="http://github.com/images/modules/header/logov3.png" alt="" /&gt;&lt;/td&gt;

&lt;td&gt;&lt;b&gt;&lt;font size="3"&gt;&lt;a href="http://github.com/CustomerFX/AccountHierarchyWeb" target="_blank"&gt;Visit the repository on Github&lt;/a&gt;&lt;br /&gt;&lt;a href="http://cloud.github.com/downloads/CustomerFX/AccountHierarchyWeb/Account_Hierarchy_for_SalesLogix_Web.zip"&gt;Download the bundle from Github&lt;/a&gt;&lt;/font&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;


&lt;p&gt;Also, I wanted to mention that the code is now &lt;a href="http://github.com/CustomerFX/AccountHierarchyWeb/blob/master/LICENSE.txt" target="_blank"&gt;licensed under the GPL version 3 license&lt;/a&gt; as well. &lt;br /&gt;&lt;/p&gt;
&lt;img src="http://customerfx.com/aggbug.aspx?PostID=41199" width="1" height="1"&gt;</content><author><name>Ryan Farley</name><uri>http://customerfx.com/members/Ryan-Farley.aspx</uri></author><category term="General" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/General/default.aspx" /><category term="SalesLogix Web" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/SalesLogix+Web/default.aspx" /><category term="Modules" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Modules/default.aspx" /><category term="Open Source" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Open+Source/default.aspx" /></entry><entry><title>Update to Git Extensions for SalesLogix Available</title><link rel="alternate" type="text/html" href="http://customerfx.com/pages/crmdeveloper/2009/12/02/update-to-git-extensions-for-saleslogix-available.aspx" /><id>http://customerfx.com/pages/crmdeveloper/2009/12/02/update-to-git-extensions-for-saleslogix-available.aspx</id><published>2009-12-02T23:10:00Z</published><updated>2009-12-02T23:10:00Z</updated><content type="html">&lt;p&gt;For anyone who uses Git Extensions for SalesLogix, I&amp;#39;ve released a small update that adds some core functionality and makes it possible to &lt;span style="font-weight:bold;"&gt;complete the entire scenario &lt;/span&gt;of setting up and using Git with a SalesLogix project - &lt;span style="font-weight:bold;font-style:italic;"&gt;all from within the SalesLogix Application Architect!&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The new functionality includes:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://customerfx.com/pages/crmdeveloper/2009/11/12/excluding-saleslogix-model-files-from-source-control.aspx"&gt;Manage files or folders to exclude from source control&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Manage remote repositories so you can link your SalesLogix project to an online or networked repository&lt;/li&gt;&lt;li&gt;Ability to open the working project folder in explorer to manage files in your model&lt;/li&gt;&lt;li&gt;Ability to initialize the current exported project model as a Git repository to start working under source control&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;See a screenshot of the complete list of functionality on the Git Extensions for SalesLogix tools menu:&lt;/p&gt;&lt;p&gt;&lt;img src="http://customerfx.com/blogs/crmdeveloper/GitExtensions_ManageRemotes.png" border="1" alt="" /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;So, you can now do the entire scenario of setting up and working with source control for your SalesLogix model. Say you have a new SalesLogix system you&amp;#39;re working with, the typical flow is as follows (again, wanted to point out you&amp;#39;re not leaving Application Architect at all in this scenario):&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Set up your new SalesLogix database&lt;/li&gt;&lt;li&gt;Export your project model&lt;/li&gt;&lt;li&gt;Click the Git Extensions &amp;quot;cow head&amp;quot; icon to initialize the exported model as a Git repository *and* a default .gitignore will be created including the &lt;a href="http://customerfx.com/pages/crmdeveloper/2009/11/12/excluding-saleslogix-model-files-from-source-control.aspx"&gt;typical entries&lt;/a&gt; for a SalesLogix model&lt;/li&gt;&lt;li&gt;Go to the Tools menu and then select &amp;quot;Manage Remote Repositories&amp;quot; to set up any remotes such as a Github repository&lt;/li&gt;&lt;li&gt;Click the Commit button on the toolbar to do your initial commit (all non-excluded model files will already be staged for the commit&lt;/li&gt;&lt;li&gt;If linked to a remote, click the Push button on the toolbar to push to the remote&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Pretty cool if you ask me.&lt;/p&gt;&lt;p&gt;To install this update, simply close Application Architect, &lt;a href="http://cloud.github.com/downloads/CustomerFX/SalesLogixGitExtensions/FX.SalesLogix.Modules.GitExtensions.dll"&gt;download the new DLL&lt;/a&gt;, and copy it over the old one located in C:\Program Files\SalesLogix\SalesLogix. If you&amp;#39;re setting it up for the first time, visit my &lt;a href="http://customerfx.com/pages/crmdeveloper/2009/10/14/announcing-git-extensions-for-saleslogix-and-the-customer-fx-open-source-initiative.aspx"&gt;initial post about Git Extensions for SalesLogix&lt;/a&gt; for setup instructions.&lt;br /&gt;&lt;/p&gt;&lt;img src="http://customerfx.com/aggbug.aspx?PostID=41182" width="1" height="1"&gt;</content><author><name>Ryan Farley</name><uri>http://customerfx.com/members/Ryan-Farley.aspx</uri></author><category term="SalesLogix" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/SalesLogix/default.aspx" /><category term="Application Architect" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Application+Architect/default.aspx" /><category term="Open Source" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Open+Source/default.aspx" /><category term="Source Control" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Source+Control/default.aspx" /><category term="Git" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Git/default.aspx" /><category term="Git Extensions for SalesLogix" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Git+Extensions+for+SalesLogix/default.aspx" /></entry><entry><title>Excluding SalesLogix Model Files from Source Control</title><link rel="alternate" type="text/html" href="http://customerfx.com/pages/crmdeveloper/2009/11/12/excluding-saleslogix-model-files-from-source-control.aspx" /><id>http://customerfx.com/pages/crmdeveloper/2009/11/12/excluding-saleslogix-model-files-from-source-control.aspx</id><published>2009-11-12T19:52:00Z</published><updated>2009-11-12T19:52:00Z</updated><content type="html">
&lt;p&gt;I love working with SalesLogix models in source control. Specifically with Git. However, whether you&amp;#39;re using Git, or some other source control system, there are certain files in a SalesLogix model that you do not want to include in your source control. Many part of the files in an exported SalesLogix model are automatically generated by the Application Architect and by the build process when you build your web platform. Having these files under source control would only complicate things when working with multiple developers since you&amp;#39;d each need to merge these automatically generated files with each pull/checkout from source control since they change every time.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;font size="4"&gt;&lt;b&gt;Model Files to Exclude&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;Let&amp;#39;s take a look at which files to exclude from source control and why.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;b&gt;ModelIndex.xml&lt;/b&gt; - This file is a temporary cache created by Application Architect as you access objects. This file can be deleted and will be automatically created again as needed. This is a volatile file and if included in source control would require constant merging with no benefit.&lt;/li&gt;

&lt;li&gt;&lt;b&gt;Model\Deployment folder tree&lt;/b&gt; - The deployment folder in the model is where the Application Architect will create all of the actual SmartPart.ascx files and other deployable items from the QuickForm meta data and entities in your model. This is not to be confused with a &amp;quot;deployment&amp;quot; per se, but this is a staging area for things to be deployed that are created when you build your platform. As you create, modify, delete items in the model and then build your web platform all of the deployment files are generated based on what is in your model. Including these files in your source control system will complicate things since these files are created all over again as you build your web platform. To keep your folder structure in tact, I usually will exclude the following from source control:&lt;/li&gt;

&lt;ul&gt;
&lt;li&gt;Model\deployment\webroot\common\SmartParts\**\*&lt;/li&gt;

&lt;li&gt;Model\deployment\webroot\common\SmartParts\**\**\*&lt;/li&gt;

&lt;li&gt;Model\deployment\webroot\common\SummaryConfigData\*&lt;/li&gt;

&lt;li&gt;Model\deployment\webroot\common\bin\*&lt;/li&gt;

&lt;li&gt;Model\deployment\webroot\common\*&lt;/li&gt;

&lt;li&gt;Model\deployment\common\bin\Sage.Entity.Interfaces.dll&lt;/li&gt;

&lt;li&gt;Model\deployment\common\bin\Sage.Form.Interfaces.dll&lt;/li&gt;
&lt;/ul&gt;

&lt;li&gt;In addition to what is excluded from the SalesLogix model, using file merge tools, such as KDiff, DiffMerge, etc, you will have additional copies of files created that you&amp;#39;ll want to exclude. When working with Git Extensions you&amp;#39;ll see these copies of files with .LOCAL, .REMOTE, .BASE extensions.&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;br /&gt;&lt;font size="4"&gt;&lt;b&gt;Ignoring Files with Git&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;As I mentioned before, I love Git. To exclude files from a Git repository you simply create a text file in the root of the repository named &amp;quot;.gitignore&amp;quot; and you can add files or directories to ignore (or to not ignore by prefixing the file or directory name with a &amp;quot;!&amp;quot;). This is what the contents of my .gitignore file looks like for a standard SalesLogix model:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;# Files created from merge tools&lt;br /&gt;*.BASE&lt;br /&gt;*.LOCAL&lt;br /&gt;*.REMOTE&lt;br /&gt;*.orig&lt;br /&gt;&lt;br /&gt;# Model files that are auto-generated&lt;br /&gt;[Mm]odel[Ii]ndex.xml&lt;br /&gt;&lt;br /&gt;# Standard deployment files&lt;br /&gt;*/deployment/webroot/common/[Ss]mart[Pp]arts/**/*&lt;br /&gt;*/deployment/webroot/common/[Ss]mart[Pp]arts/**/**/*&lt;br /&gt;*/deployment/webroot/common/[Ss]ummary[Cc]onfig[Dd]ata/*&lt;br /&gt;*/deployment/webroot/common/bin/*&lt;br /&gt;*/deployment/webroot/common/*&lt;br /&gt;*/deployment/common/bin/[Ss]age.[Ee]ntity.[Ii]nterfaces.dll&lt;br /&gt;*/deployment/common/bin/[Ss]age.[Ff]orm.[Ii]nterfaces.dll&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;font size="4"&gt;&lt;b&gt;Ignoring Files with Git Extensions for SalesLogix&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;To make all of this easier with working with Git for source control with a SalesLogix model, I have updated Git Extensions for SalesLogix. The menu in Application Architect now includes a menu option to edit your .gitignore, and if it does not yet exist, it will give you the option to add all of the standard entries I have mentioned above. &lt;/p&gt;&lt;p&gt;&lt;img src="http://customerfx.com/blogs/crmdeveloper/GitIgnore_Menu.png" border="1" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="http://customerfx.com/blogs/crmdeveloper/GitIgnore_Message.png" border="1" alt="" /&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;In addition, when you initialize a new Git repository for a model from Application Architect the .gitignore file will be automatically created for you wit the entries mentioned above. Note, when you open a model in Application Architect and click the browse button on the Git Extensions toolbar it will detect if the current model has a Git repository or not and will prompt you to create the repository if one does not yet exist.&lt;/p&gt;&lt;p&gt;To download this update to Git Extensions for SalesLogix, just &lt;a href="http://cloud.github.com/downloads/CustomerFX/SalesLogixGitExtensions/FX.SalesLogix.Modules.GitExtensions.dll"&gt;download the new DLL&lt;/a&gt; and copy it over the old one. Take a look a &lt;a href="http://wiki.github.com/CustomerFX/SalesLogixGitExtensions/installation" target="_blank"&gt;the project wiki for full installation steps&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt;
&lt;img src="http://customerfx.com/aggbug.aspx?PostID=41108" width="1" height="1"&gt;</content><author><name>Ryan Farley</name><uri>http://customerfx.com/members/Ryan-Farley.aspx</uri></author><category term="SalesLogix" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/SalesLogix/default.aspx" /><category term="Application Architect" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Application+Architect/default.aspx" /><category term="Tools" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Tools/default.aspx" /><category term="Open Source" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Open+Source/default.aspx" /><category term="Source Control" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Source+Control/default.aspx" /><category term="Git" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Git/default.aspx" /><category term="Git Extensions for SalesLogix" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Git+Extensions+for+SalesLogix/default.aspx" /></entry><entry><title>The Official Sage SData Specification Released</title><link rel="alternate" type="text/html" href="http://customerfx.com/pages/crmdeveloper/2009/11/05/the-official-sage-sdata-specification-released.aspx" /><id>http://customerfx.com/pages/crmdeveloper/2009/11/05/the-official-sage-sdata-specification-released.aspx</id><published>2009-11-05T21:48:00Z</published><updated>2009-11-05T21:48:00Z</updated><content type="html">&lt;p&gt;The official Sage SData Specification has now been released. SData (which stands for &amp;quot;Sage Data&amp;quot;) is a Sage communication protocol. Using SData you have a common protocol that defines data access, consumption, and exchange between Sage application and 3rd party applications as well. The SData specification is now released and public.&lt;/p&gt;
&lt;p&gt;The new Sage website, sdata.sage.com, provides all the details and the complete specification. Take a look:&lt;/p&gt;
&lt;p&gt;&lt;img border="0" align="absMiddle" src="http://customerfx.com/blogs/crmdeveloper/SData-32x32.png" alt="" /&gt;&amp;nbsp; &lt;a href="http://sdata.sage.com/" target="_blank"&gt;&lt;font size="4"&gt;&lt;b&gt;View the SData Specification website&lt;/b&gt;&lt;/font&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The SData 1.0 specification brings some exciting new possibilities for the future of Sage products. For companies that use multiple products from Sage such as SalesLogix, MAS, SageCRM, etc, there will be some great things that this will make possible. However, even more exciting for me are the possibilities of developing 3rd party applications that work with Sage products using SData for communication.&lt;/p&gt;
&lt;p&gt;Some of the more exciting areas I&amp;#39;d suggest you take a look at are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://sdata.sage.com/downloads/SDataCoreWiki.pdf" target="_blank"&gt;The SData Core Specification (PDF)&lt;/a&gt; (Get up to speed on how to construct SData feed URLs and services)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://interop.sage.com/daisy/sdata/Introduction.html" target="_blank"&gt;The SData Core Specification (Online version)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://sdata.sage.com/sdatacore_covers.html" target="_blank"&gt;SData under the covers&lt;/a&gt; (great intro for those not familiar with SData yet)&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://sdata.sage.com/sdatacore_showcases.html" target="_blank"&gt;SData Showcases &amp;amp; Downloads&lt;/a&gt; (some sample apps, like an Outlook contact import, and Excel addin for consuming SData, as well as an SData validation tool)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://sdata.sage.com/sdatacust.html" target="_blank"&gt;SData Custom Extensions&lt;/a&gt; (for a look at some extension contracts for global data exchange between different applications)&lt;/li&gt;&lt;/ul&gt;One thing for sure, the website does put to REST (unintentional pun) the unclarity of the casing of the name. It should be henceforth referred to as &amp;quot;SData&amp;quot;, not &amp;quot;sData&amp;quot;.&lt;br /&gt;&lt;img src="http://customerfx.com/aggbug.aspx?PostID=41086" width="1" height="1"&gt;</content><author><name>Ryan Farley</name><uri>http://customerfx.com/members/Ryan-Farley.aspx</uri></author><category term="SalesLogix" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/SalesLogix/default.aspx" /><category term="Documentation" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Documentation/default.aspx" /><category term="SData" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/SData/default.aspx" /></entry><entry><title>Preview of Git Extensions for SalesLogix</title><link rel="alternate" type="text/html" href="http://customerfx.com/pages/crmdeveloper/2009/10/15/preview-of-git-extensions-for-saleslogix.aspx" /><id>http://customerfx.com/pages/crmdeveloper/2009/10/15/preview-of-git-extensions-for-saleslogix.aspx</id><published>2009-10-15T20:58:00Z</published><updated>2009-10-15T20:58:00Z</updated><content type="html">&lt;p&gt;&lt;a href="http://customerfx.com/pages/crmdeveloper/2009/10/14/announcing-git-extensions-for-saleslogix-and-the-customer-fx-open-source-initiative.aspx"&gt;Yesterday I announced&lt;/a&gt; my new project &lt;b&gt;Git Extensions for SalesLogix&lt;/b&gt;. I received a lot of e-mails from people who read that post, so I thought it would be a good idea to record a quick video so you can see it in action and get a better idea how it works. This quick 4-5 minute video will show you how to commit changes in Application Architect to a Git repository and push the changes to an online repository as well, all from inside Application Architect using Git Extensions for SalesLogix. You&amp;#39;ll also get a peek at a few other pieces of functionality as well. All in all, if you already use Git Extensions then this will be a no-brainer to use. If you&amp;#39;re new to Git, or to source control at all, then this will lower the learning curve significantly and make things much easier to get into.&lt;/p&gt;
&lt;p&gt;&lt;font size="4"&gt;&lt;b&gt;Watch the Preview Video&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="http://customerfx.com/blogs/crmdeveloper/logo.png" border="0" alt="" /&gt;&amp;nbsp;&lt;/p&gt;

&lt;table&gt;&lt;tr&gt;
&lt;td&gt;&lt;a href="http://www.screencast.com/t/Q4TwBvqWm" target="_blank" title="Watch the Git Extensions for SalesLogix Video"&gt;&lt;img src="http://customerfx.com/blogs/crmdeveloper/play.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;font size="3"&gt;&lt;b&gt;&lt;a href="http://www.screencast.com/t/Q4TwBvqWm" target="_blank" title="Watch the Git Extensions for SalesLogix Video"&gt;Watch the Git Extensions for SalesLogix Preview Video&lt;/a&gt;&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#404040"&gt;&lt;i&gt;The video will open on screencast.com in a new window&lt;/i&gt;&lt;/font&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;Well, that should give you an idea of how Git Extension for SalesLogix works and allow you to jump into things easier. Take a look at my &lt;a href="http://customerfx.com/pages/crmdeveloper/2009/10/14/announcing-git-extensions-for-saleslogix-and-the-customer-fx-open-source-initiative.aspx"&gt;previous post&lt;/a&gt; to see how to get to the Git Extensions for SalesLogix repository on Github if you&amp;#39;re interested and more importantly, the installation instructions.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;See &lt;a href="http://customerfx.com/pages/crmdeveloper/2009/10/14/announcing-git-extensions-for-saleslogix-and-the-customer-fx-open-source-initiative.aspx"&gt;Announcing Git Extensions for SalesLogix and the Customer FX Open Source Initiative&lt;/a&gt; &lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;As always, feedback is welcome. Thanks and enjoy. &lt;br /&gt;&lt;/p&gt;
&lt;img src="http://customerfx.com/aggbug.aspx?PostID=40999" width="1" height="1"&gt;</content><author><name>Ryan Farley</name><uri>http://customerfx.com/members/Ryan-Farley.aspx</uri></author><category term="SalesLogix" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/SalesLogix/default.aspx" /><category term="Application Architect" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Application+Architect/default.aspx" /><category term="Open Source" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Open+Source/default.aspx" /><category term="Source Control" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Source+Control/default.aspx" /><category term="Git" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Git/default.aspx" /><category term="Git Extensions for SalesLogix" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Git+Extensions+for+SalesLogix/default.aspx" /></entry><entry><title>Announcing Git Extensions for SalesLogix and the Customer FX Open Source Initiative</title><link rel="alternate" type="text/html" href="http://customerfx.com/pages/crmdeveloper/2009/10/14/announcing-git-extensions-for-saleslogix-and-the-customer-fx-open-source-initiative.aspx" /><id>http://customerfx.com/pages/crmdeveloper/2009/10/14/announcing-git-extensions-for-saleslogix-and-the-customer-fx-open-source-initiative.aspx</id><published>2009-10-14T21:51:00Z</published><updated>2009-10-14T21:51:00Z</updated><content type="html">&lt;p&gt;This blog post is the first of many that will cover the topics of using source control with SalesLogix development, Customer FX&amp;#39;s open source initiative, and the new Git Extensions for SalesLogix module for Application Architect. These are three things I am completely excited about. Using source control with SalesLogix development in Application Architect is a necessity if you want to do it right. Git Extensions for SalesLogix is the first of the Customer FX open source initiative that builds on the idea of using source control with SalesLogix development to make it even easier to use Git source control right from inside Application Architect as a natural, built-in part of the application.&lt;/p&gt;

&lt;p style="font-weight:bold;"&gt;&lt;font size="4"&gt;The Customer FX Open Source Initiative&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;Before we get to the details about Git Extensions for SalesLogix, I want to mention a few things about the Customer FX Open Source Initiative. For years, Customer FX has been a consistent source of information in the SalesLogix community. We make it a point to post anything interesting or useful to our blogs. It is great to work for a company that puts so much emphasis on sharing with the community. After all, when the community thrives, we all benefit. The management team at Customer FX actually factors in blogging time into everyone&amp;#39;s schedule to make it easy for us to share what we know.&lt;/p&gt;

&lt;p&gt;We are going to start taking that a step further. Not only will we be sharing knowledge, but we&amp;#39;ll be sharing code now too. There will be much more to come on this topic,&amp;nbsp;so stay tuned and you&amp;#39;ll start to see more and more open source projects coming from Customer FX. We hope to pick up some collaborators from the community as well. The first of our open source projects is the Git Extensions for SalesLogix module. Read on.&lt;/p&gt;

&lt;p&gt;&lt;font size="4"&gt;&lt;span style="font-weight:bold;"&gt;Using Source Control with SalesLogix Development&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;I&amp;#39;m not going to spend too much time talking about this topic since it deserves much more individualized attention. But, if you work in Application Architect customizing SalesLogix and you&amp;#39;re not using source control. I hear your pain. Using source control for your SalesLogix models is the only way to do it right. My personal favorite is Git, so much of my information will be covering Git source control, however, I do plan on touching on Subversion from time to time as well.&lt;/p&gt;

&lt;p&gt;&lt;font size="4"&gt;&lt;span style="font-weight:bold;"&gt;Git Extensions for SalesLogix&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="http://customerfx.com/blogs/crmdeveloper/logo.png" border="0" alt="" /&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;So, without further ado, let&amp;#39;s take a quick look at my new Git Extensions for SalesLogix module. Git Extensions for SalesLogix is a module for Application Architect that extends AA to include the most common Git functions, right on the AA toolbar and menus. Imagine this, you open a form in AA, make some changes, then click a button on the toolbar in AA to commit the change. Later, you click another button on the AA toolbar to push back to your online repository. All without ever leaving Application Architect. This is what Git Extensions for SalesLogix gives you. Well that, and a break from some headaches. Git Extensions for SalesLogix integrates the completely awesome open source &lt;a href="http://code.google.com/p/gitextensions/" target="_blank"&gt;Git Extensions&lt;/a&gt; into Application Architect. So to use Git Extensions for SalesLogix, you&amp;#39;ll also need to have Git Extensions installed.&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;Here&amp;#39;s a screenshot of Application Architect with Git Extensions for SalesLogix loaded:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://customerfx.com/blogs/crmdeveloper/GitExtensionsForSalesLogix_CompleteWithMenu2.png" title="Git Extensions for SalesLogix" target="_blank"&gt;&lt;img src="http://customerfx.com/blogs/crmdeveloper/th_GitExtensionsForSalesLogix_CompleteWithMenu2.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;font size="2"&gt;&lt;span style="font-style:italic;"&gt;&amp;nbsp;(Click for a larger view)&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;Git Extensions for SalesLogix is fully functional and will likely grow to include many more functions in the future. You can grab this now and use it. You can also grab the code and submit patches for any changes you&amp;#39;d like to make. If you would like to collaborate submit a patch and I&amp;#39;ll add you as a collaborator (or just ask). Take a look below for details on the repository location, or to just install it. &lt;/p&gt;

&lt;table&gt;

&lt;tr&gt;
&lt;td&gt;&lt;img src="http://github.com/images/modules/header/logov3.png" alt="" /&gt;&lt;/td&gt;

&lt;td&gt;&lt;b&gt;&lt;font size="3"&gt;&lt;a href="http://github.com/CustomerFX/SalesLogixGitExtensions" target="_blank"&gt;Visit the Git Extensions for SalesLogix Repository&lt;/a&gt;&lt;/font&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;To install Git Extensions for SalesLogix visit the &lt;a href="http://wiki.github.com/CustomerFX/SalesLogixGitExtensions/installation" target="_blank"&gt;Installation page in the project Wiki on Github&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Keep in mind, the initial version of this module was cranked out all in one night, so you&amp;#39;re bound to find some bugs. I&amp;#39;ve only tested it so far in 7.5.2 and 7.5.1 (versions prior to 7.5.2 will have some funky placement of separators on the toolbar and menus). Also, the next version will no longer need to modify the XML file listed above (steps 4-6) and you&amp;#39;ll just be able to drop the DLL into the modules folder in the SalesLogix directory.&lt;/p&gt;

&lt;p&gt;Enjoy, and I hope to get some feedback from others who wish to use the module. Also, for anyone who would like to use source control but just don&amp;#39;t know how, I am considering offering a training class on using source control with SalesLogix and working in a multi-developer environment. Let me know if you&amp;#39;d be interested.&lt;/p&gt;
&lt;p&gt;&lt;i&gt;&lt;b&gt;Update:&lt;/b&gt; Don&amp;#39;t miss my next post where I show a video preview of Git Extensions for SalesLogix in action. &lt;a href="http://customerfx.com/pages/crmdeveloper/2009/10/15/preview-of-git-extensions-for-saleslogix.aspx"&gt;View it now&lt;/a&gt;.&lt;/i&gt; &lt;br /&gt;&lt;/p&gt;
&lt;img src="http://customerfx.com/aggbug.aspx?PostID=40994" width="1" height="1"&gt;</content><author><name>Ryan Farley</name><uri>http://customerfx.com/members/Ryan-Farley.aspx</uri></author><category term="SalesLogix" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/SalesLogix/default.aspx" /><category term="Application Architect" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Application+Architect/default.aspx" /><category term="Open Source" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Open+Source/default.aspx" /><category term="Source Control" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Source+Control/default.aspx" /><category term="Git" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Git/default.aspx" /><category term="Git Extensions for SalesLogix" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Git+Extensions+for+SalesLogix/default.aspx" /></entry><entry><title>Adding Custom Controls to Application Architect in SalesLogix 7.5.2</title><link rel="alternate" type="text/html" href="http://customerfx.com/pages/crmdeveloper/2009/10/08/adding-custom-controls-to-application-architect-in-saleslogix-7-5-2.aspx" /><id>http://customerfx.com/pages/crmdeveloper/2009/10/08/adding-custom-controls-to-application-architect-in-saleslogix-7-5-2.aspx</id><published>2009-10-09T00:25:00Z</published><updated>2009-10-09T00:25:00Z</updated><content type="html">&lt;p&gt;I just came across some new info that has been added to SalesLogix 7.5.2 (currently in beta). The ability to add custom controls to Application Architect &lt;b&gt;for use on QuickForms&lt;/b&gt;. This is a completely welcome and awesome addition to the SalesLogix Application Architect. The following is taken from the 7.5.2 AA help files:&lt;/p&gt;


&lt;blockquote&gt;&lt;p&gt;&lt;span&gt;&lt;i&gt;Note: The following applies to 7.5.2 and higher only&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;h1&gt;Creating Custom Controls for Quick Forms&lt;/h1&gt;
&lt;p&gt;You can create custom controls and use them in Application Architect Quick 
Forms.&lt;/p&gt;
&lt;p class="Infinitive"&gt;&lt;b&gt;To create&lt;/b&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create a new Visual Studio project with the class 
library template.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add project references to Sage.Platform, 
Sage.Platform.Application, and Sage.Platform.QuickForms.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a class that derives from 
QuickFormsControlBase or any control you want to extend.&amp;nbsp;
&lt;/p&gt;
&lt;div style="position:relative;" id="POPUP143351357_tmp" class="droptext"&gt;
&lt;p&gt;Location of classes mentioned is: 
Sage.Platform.QuickForms.Controls.QuickFormsControlBase and 
Sage.Platform.QuickForms.Controls.QFTextBox.&lt;/p&gt;
&lt;p&gt;Following is a code shell for extending a TextBox control:&lt;/p&gt;
&lt;p class="code-snippet"&gt;using Sage.Platform.QuickForms.Controls;&lt;br /&gt;namespace 
CustomQuickFormControls&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [BindableProperty(RenderPlatform.Web, &amp;quot;Text&amp;quot;, 
true)]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public class CustomTextBox : QuickFormsControlBase, 
ICustomTextBox&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public string MyProperty { get; set; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public bool 
IsRight { get; set; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public string Text { get; set; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add the properties to collect the information 
needed to generate the markup for your custom ASP.NET control.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Enable code snippet actions to refer to the custom 
control by wrapping it with an adapter.
&lt;/p&gt;
&lt;div style="position:relative;" id="POPUP187059069_tmp" class="droptext"&gt;
&lt;ol&gt;
&lt;li class="kadov-p-CTopic-Text-Lettered"&gt;
&lt;p class="Topic-Text-Lettered"&gt;Create an interface that represents the control, 
for example, ICustomTextBox. &lt;/p&gt;
&lt;/li&gt;
&lt;li class="kadov-p-CTopic-Text-Lettered"&gt;
&lt;p class="Topic-Text-Lettered"&gt;Implement the interface in the custom quick form 
control class. &lt;/p&gt;
&lt;/li&gt;
&lt;li class="kadov-p-CTopic-Text-Lettered"&gt;
&lt;p class="Topic-Text-Lettered"&gt;Create a control adapter that implements the 
interface. &lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p class="Topic-Text-Indent2"&gt;The adapter will have a reference to the underlying 
control and acts as a wrapper for it.&lt;/p&gt;
&lt;ol start="4"&gt;
&lt;li class="kadov-p-CTopic-Text-Lettered"&gt;
&lt;p class="Topic-Text-Lettered"&gt;Copy the assembly containing the adapter into the 
website bin in the active model, for example, 
Model\Portal\SlxClient\SupportFiles\Bin. &lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;See the Sage.SalesLogix.Web.controls.Adapters namespace (in 
Sage.SalesLogix.Web.Controls.dll) for examples.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Copy the assembly containing the control class into 
the same location as SageAppArchitect.exe, for example, C:\Program 
Files\SalesLogix.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add the assembly name to the 
QuickFormsConfiguration.xml file in order to add it to the list of controls in 
Application Architect.&amp;nbsp;
&lt;/p&gt;
&lt;div style="position:relative;" id="POPUP143458579_tmp" class="droptext"&gt;
&lt;ul&gt;
&lt;li class="kadov-p-CBullets"&gt;
&lt;p class="Bullets"&gt;Add a &amp;lt;string&amp;gt; node for the dll containing the new 
control class to the &amp;lt;ControlAssemblyRegistryserialized&amp;gt; node.&lt;/p&gt;
&lt;/li&gt;
&lt;li class="kadov-p-CBullets"&gt;
&lt;p class="Bullets"&gt;Application Architect creates the XML file the first time it 
opens after installation. It places it in 
C:\ProgramData\Sage\Platform\Configuration\Application\SalesLogix (Vista) or 
C:\Documents and Settings\All Users\Application 
Data\Sage\Platform\Configuration\Application\SalesLogix (Windows 
2008).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create an NVelocity template for rendering your 
custom control and put it in your active model at Model\QuickForms\Web. See 
other templates in this folder for examples.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add a &amp;lt;WebControlRenderingProvider&amp;gt; node to 
the Web.ControlConfiguration.xml file.
&lt;/p&gt;
&lt;div style="position:relative;" id="POPUP143528773_tmp" class="droptext"&gt;
&lt;ul&gt;
&lt;li class="kadov-p-CBullets"&gt;
&lt;p class="Bullets"&gt;Locate the xml file in the model, Model\QuickForms\Web.&lt;/p&gt;
&lt;/li&gt;
&lt;li class="kadov-p-CBullets"&gt;
&lt;p class="Bullets"&gt;The node provides the information needed by the control 
rendering engine. Follow examples in the file.&lt;/p&gt;
&lt;/li&gt;
&lt;li class="kadov-p-CBullets"&gt;
&lt;p class="Bullets"&gt;Reference the NVelocity template you created.&lt;/p&gt;
&lt;/li&gt;
&lt;li class="kadov-p-CBullets"&gt;
&lt;p class="Bullets"&gt;Provide a PropertyMaps property for any quick form properties 
with names that differ from their corresponding properties in the rendered 
control. For example, the quick form control property, Style Scheme, is mapped 
to the web control property of CssClass.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The generator uses PropertyMaps when generating data 
binding code. &lt;br /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Cool indeed. No doubt that I will be covering more on this topic in the very near future.&lt;br /&gt;&lt;/p&gt;
&lt;img src="http://customerfx.com/aggbug.aspx?PostID=40968" width="1" height="1"&gt;</content><author><name>Ryan Farley</name><uri>http://customerfx.com/members/Ryan-Farley.aspx</uri></author><category term="Application Architect" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Application+Architect/default.aspx" /><category term="Quick Forms" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Quick+Forms/default.aspx" /><category term="SalesLogix 7.5.2" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/SalesLogix+7.5.2/default.aspx" /><category term="Custom Controls" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Custom+Controls/default.aspx" /></entry><entry><title>Flattening Out SalesLogix Data To Combine Multiple Rows into a Single String using SQL</title><link rel="alternate" type="text/html" href="http://customerfx.com/pages/crmdeveloper/2009/10/01/flattening-out-saleslogix-data-to-combine-multiple-rows-into-a-single-string-using-sql.aspx" /><id>http://customerfx.com/pages/crmdeveloper/2009/10/01/flattening-out-saleslogix-data-to-combine-multiple-rows-into-a-single-string-using-sql.aspx</id><published>2009-10-01T17:43:00Z</published><updated>2009-10-01T17:43:00Z</updated><content type="html">
&lt;p&gt;A question came up from a person attending our current Report Writing class about how to flatten out data that exists as multiple rows in the database to a single string in a report. There is a really cool trick you can do in SQL to accomplish this which I previously outlined here:&lt;/p&gt;

&lt;p&gt;See &lt;a href="http://ryanfarley.com/blog/archive/2005/02/17/1712.aspx" target="_blank"&gt;Flattening Out Data with One of the Coolest SQL Tricks Ever&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this post from 2005 I outline a technique that can be used to make a query append each value from the rows in the query to a variable. Without using cursors, you will end up with a variable that has the values appended to it as one single string. Go read my original post to understand this technique further (I&amp;#39;ll wait).&lt;/p&gt;

&lt;p&gt;Now, that you&amp;#39;ve read that, let&amp;#39;s look at a practical example of using that technique with SalesLogix Data so that it could be included in a report. In this sample, we will be combining all rows of activity data (the date and description only) into a single string for each contact. So, instead of having multiple rows of activities for each contact, we&amp;#39;ll end up with a string of activities like this: &amp;quot;3/2/2009 Lunch Meeting, 4/20/2009 Appoinement, 8/10/2009 Follow-up Call&amp;quot;.&lt;/p&gt;

&lt;p&gt;There are two database objects we&amp;#39;ll need to create. First, we&amp;#39;ll create a SQL function. This function will take in a parameter of a ContactID and will return a string of activities for that contact. This function will look like this:&lt;/p&gt;


&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;span style="color:Blue;"&gt;create&lt;/span&gt; &lt;span style="color:Blue;"&gt;function&lt;/span&gt; sysdba.GetActivityListForContact
(
    @contactid &lt;span style="color:Blue;"&gt;varchar&lt;/span&gt;(12)
)
&lt;span style="color:Blue;"&gt;returns&lt;/span&gt; &lt;span style="color:Blue;"&gt;varchar&lt;/span&gt;(8000)
&lt;span style="color:Blue;"&gt;as&lt;/span&gt;
&lt;span style="color:Blue;"&gt;begin&lt;/span&gt;

    &lt;span style="color:Blue;"&gt;declare&lt;/span&gt; @list &lt;span style="color:Blue;"&gt;varchar&lt;/span&gt;(8000)
    &lt;span style="color:Blue;"&gt;set&lt;/span&gt; @list = &lt;span style="color:Navy;"&gt;&amp;#39;&amp;#39;&lt;/span&gt;

    &lt;span style="color:Blue;"&gt;select&lt;/span&gt; 
        @list = @list + &lt;span style="color:Blue;"&gt;convert&lt;/span&gt;(&lt;span style="color:Blue;"&gt;varchar&lt;/span&gt;, a.startdate, 101) + &lt;span style="color:Navy;"&gt;&amp;#39; &amp;#39;&lt;/span&gt; + a.description + &lt;span style="color:Navy;"&gt;&amp;#39;, &amp;#39;&lt;/span&gt; 
    &lt;span style="color:Blue;"&gt;from&lt;/span&gt; 
        sysdba.activity a 
    &lt;span style="color:Blue;"&gt;where&lt;/span&gt; 
        a.contactid = @contactid 
    &lt;span style="color:Blue;"&gt;order&lt;/span&gt; &lt;span style="color:Blue;"&gt;by&lt;/span&gt; 
        a. startdate

    &lt;span style="color:Blue;"&gt;set&lt;/span&gt; @list = rtrim(@list)
    &lt;span style="color:Blue;"&gt;if&lt;/span&gt; @list &amp;lt;&amp;gt; &lt;span style="color:Navy;"&gt;&amp;#39;&amp;#39;&lt;/span&gt; &lt;span style="color:Blue;"&gt;set&lt;/span&gt; @list = &lt;span style="color:Blue;"&gt;left&lt;/span&gt;(@list, len(@list) - 1)

    &lt;span style="color:Blue;"&gt;return&lt;/span&gt; @list 

&lt;span style="color:Blue;"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;


&lt;p&gt;Now that we have that function, we can use it in a query, or wrap it in a SQL view as follows:&lt;/p&gt;


&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre&gt;&lt;span style="color:Blue;"&gt;create&lt;/span&gt; &lt;span style="color:Blue;"&gt;view&lt;/span&gt; sysdba.vContactExtended 
&lt;span style="color:Blue;"&gt;as&lt;/span&gt;

    &lt;span style="color:Blue;"&gt;select&lt;/span&gt; 
          *
        , sysdba.GetActivityListForContact(contactid) &lt;span style="color:Blue;"&gt;as&lt;/span&gt; ActivityList 
    
    &lt;span style="color:Blue;"&gt;from&lt;/span&gt; 
        sysdba.contact &lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;


&lt;p&gt;Now you can just add your vContactExtended view into the report and you&amp;#39;ll have the new ActivityList column added where you&amp;#39;ll see the activities listed all in a single field.&lt;br /&gt;&lt;/p&gt;
&lt;img src="http://customerfx.com/aggbug.aspx?PostID=40922" width="1" height="1"&gt;</content><author><name>Ryan Farley</name><uri>http://customerfx.com/members/Ryan-Farley.aspx</uri></author><category term="Views" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Views/default.aspx" /><category term="Query" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Query/default.aspx" /><category term="Database" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Database/default.aspx" /><category term="SQL" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/SQL/default.aspx" /><category term="Reporting" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Reporting/default.aspx" /></entry><entry><title>Groups Not Loading in SalesLogix 7.5 Web</title><link rel="alternate" type="text/html" href="http://customerfx.com/pages/crmdeveloper/2009/08/31/groups-not-loading-in-saleslogix-7-5-web.aspx" /><id>http://customerfx.com/pages/crmdeveloper/2009/08/31/groups-not-loading-in-saleslogix-7-5-web.aspx</id><published>2009-08-31T21:08:00Z</published><updated>2009-08-31T21:08:00Z</updated><content type="html">&lt;p&gt;I recently saw an issue where groups would not load in SalesLogix 7.5.1 web. Not a single group would load. You&amp;#39;d see the spinning circle as if it were attempting to load the group. However, that would disappear and then...nothing. No group data would appear. Not just the data, but not even the group definition, so you wouldn&amp;#39;t even see any column headers. With a little troubleshooting the problem was easy to track down, and the solution turned out to be a simple one.&lt;/p&gt;&lt;p style="font-weight:bold;"&gt;&lt;font size="4"&gt;&lt;br /&gt;The Problem&lt;/font&gt;&lt;/p&gt;&lt;p&gt;The problem was that no groups would load. None. Not for any user at all. It would look as if it were loading, but then you&amp;#39;d end up with nothing at all. No data, not even the column headers would show up as seen in the screenshot below:&lt;/p&gt;&lt;p&gt;&lt;img src="http://customerfx.com/blogs/crmdeveloper/SlxWeb_NoGroups_Issue2.png" border="0" alt="" /&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Pretty frustrating since I had some difficulty thinking where I should start looking. Let&amp;#39;s go through the process I followed to find the issue and solution before we just right to the fix.&lt;/p&gt;&lt;p&gt;&lt;font size="4"&gt;&lt;span style="font-weight:bold;"&gt;&lt;br /&gt;Troubleshooting to Discover the Cause &lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;It is sometimes difficult to know where to start with an issue like this. One thing I did know is that the groups are loaded asynchronously, from the client (not loaded on the server and returned to the page). So, it made sense that I would see a request being made from my browser to get the group data. There is a great tool to see that sort of thing called &lt;a href="http://www.fiddlertool.com/" target="_blank"&gt;Fiddler&lt;/a&gt;. Fiddler is a tool that will let you monitor and watch all HTTP traffic from your computer to the server. Looking at the traffic we should see this request and hopefully it will tell us something useful as to why the data is not returning. &lt;/p&gt;&lt;p&gt;&lt;img src="http://customerfx.com/blogs/crmdeveloper/SlxWeb_NoGroups_Fiddler.png" border="0" height="506" width="680" alt="" /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Looking at the traffic from my computer to the server hosting SalesLogix there is one item that stands out. A request is returning an HTTP 500 error (which indicates an error occurred on the server executing the request). The URL being accessed is the following:&lt;/p&gt;&lt;p style="margin-left:40px;"&gt;http://saleslogix.customerfx.com/client/slxdata.ashx/slx/groups?family=TICKET&amp;amp;name=Ryans%20Tickets&amp;amp;format=json&amp;amp;meta=true&amp;amp;_dc=1251755197076&amp;amp;start=0&amp;amp;limit=150&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Also, worth noting is that the request is returning the typical ASP.NET error. Ah. That will help. If the request is throwing an unhandled error it should be logged in the event logs on the server. &lt;/p&gt;&lt;p&gt;Looking in the event logs we can find the following error logged:&lt;/p&gt;&lt;p style="margin-left:40px;"&gt;Event Type:&amp;nbsp;&amp;nbsp;&amp;nbsp; Error&lt;br /&gt;Event Source:&amp;nbsp;&amp;nbsp;&amp;nbsp; Sage.SData.Service&lt;br /&gt;Event Category:&amp;nbsp;&amp;nbsp;&amp;nbsp; None&lt;br /&gt;Event ID:&amp;nbsp;&amp;nbsp;&amp;nbsp; 0&lt;br /&gt;Date:&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; 8/31/2009&lt;br /&gt;Time:&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; 4:45:31 PM&lt;br /&gt;User:&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; N/A&lt;br /&gt;Computer:&amp;nbsp;&amp;nbsp;&amp;nbsp; CFXWEB&lt;br /&gt;Description:&lt;br /&gt;Exception caught during the processing of a message&lt;br /&gt;&lt;br /&gt;Verb: GET&lt;br /&gt;Uri: http://saleslogix.customerfx.com/client/slxdata.ashx/slx/groups?family=TICKET&amp;amp;name=Ryans Tickets&amp;amp;format=json&amp;amp;meta=true&amp;amp;_dc=1251755197076&amp;amp;start=0&amp;amp;limit=150&lt;br /&gt;&lt;br /&gt;Original Message: Thread was being aborted.&lt;br /&gt;&lt;br /&gt;Stack Trace:&amp;nbsp;&amp;nbsp;&amp;nbsp; at Sage.SalesLogix.Client.GroupBuilder.SLXSchemaInfo.RebuildXMLSchema(String constring, Boolean forceRebuild)&lt;br /&gt;&amp;nbsp;&amp;nbsp; at Sage.SalesLogix.Client.GroupBuilder.GroupInfo.GetXMLSchemaDocument()&lt;br /&gt;&amp;nbsp;&amp;nbsp; at Sage.SalesLogix.Client.GroupBuilder.GroupInfo.GetColumnsForTable(String TableName)&lt;br /&gt;&amp;nbsp;&amp;nbsp; at Sage.SalesLogix.Client.GroupBuilder.GroupInfo.UseUCField(String sortOn)&lt;br /&gt;&amp;nbsp;&amp;nbsp; at Sage.SalesLogix.Client.GroupBuilder.GroupsRequest.GetGroup(IRequest request)&lt;br /&gt;&amp;nbsp;&amp;nbsp; at Invoke58748ac5b47c438e91099062b3de65cf.Invoke(Object , IRequest )&lt;br /&gt;&amp;nbsp;&amp;nbsp; at Sage.Integration.Messaging.RequestTargetRegistration.RequestTargetInvoker.Invoke(IRequest request)&lt;br /&gt;&amp;nbsp;&amp;nbsp; at Sage.Integration.Messaging.Request.Process(RequestTargetInvoker invoker)&lt;br /&gt;&amp;nbsp;&amp;nbsp; at Sage.Integration.Messaging.MessagingService.Process(IRequest request)&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Now we are getting somewhere. Looking at the stack trace we can see that the place this error is coming from is in the SLXSchemaInfo.RebuildXMLSchema method in the Sage.SalesLogix.Client.GroupBuilder.dll. Let&amp;#39;s open up &lt;a href="http://www.red-gate.com/products/reflector/" target="_blank"&gt;Reflector&lt;/a&gt; and take a look at what is going on there.&lt;/p&gt;&lt;p&gt;&lt;img src="http://customerfx.com/blogs/crmdeveloper/SlxWeb_NoGroups_Reflector1.png" border="0" alt="" /&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;We know the error is happening when this method is called (last method shown in the stack trace). Going through it we see that the first item called is &amp;quot;isRebuildFlagged&amp;quot;. The code in that method checks the results of the following query:&lt;/p&gt;&lt;p style="margin-left:40px;"&gt;select datacode from plugin where pluginid=&amp;#39;XMLSCHEMA&amp;#39;&lt;/p&gt;&lt;p&gt;If the value returned by that query equals &amp;quot;REBUILD_SCHEMA&amp;quot; then it flags to the code to proceed and then &amp;quot;loadDbschema&amp;quot; is called. In this method the XML Schema is recreated and saved to the database. Checking this query in the SalesLogix database I could see that the value returned was &amp;quot;REBUILD_SCHEMA&amp;quot;. So, that is what is causing my problem, when the schema is being rebuilt.&lt;/p&gt;&lt;p&gt;Looking again at the event logs on the server that there was also another error logged immediately following the one I mentioned earlier. The error text logged was:&lt;/p&gt;&lt;p style="margin-left:40px;"&gt;System.Web.HttpException: Request timed out.&lt;/p&gt;&lt;p&gt;The real issue here then, is that the call to rebuild the schema is timing out. It is taking longer to call the method to rebuild the schema than the default timeout setting on the server (the default ASP.NET execution timeout is 90 seconds).&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;font size="4"&gt;&lt;span style="font-weight:bold;"&gt;The Solution(s)&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;Now that we know exactly what is causing the issue we can come up with a few reasonable solutions to fix it. Note, you do not have to do all of these, any single one of these solutions would work. &lt;br /&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Increase the timeout on the server. To increase this you can open the web.config and look for the executionTimeout attribute in the httpRuntime node. This value will be set to 90 if it hasn&amp;#39;t been changed before. Increase this number to a value large enough (in seconds) to allow the operation to complete. This will allow this to execute again in the future if needed, but use extreme caution when increasing the value to something too large as you&amp;#39;ll be opening yourself up to potential attacks. &lt;br /&gt;&lt;/li&gt;&lt;li&gt;Open the LAN client and do something that will cause the XML schema to be rebuilt. One way to do this is to attempt to create a merge form. This will rebuild the schema if needed. This is a one time fix. If the schema changes and this flag is set again then this will need to be done again.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Simply clear the &amp;quot;REBUILD_SCHEMA&amp;quot; flag from the datacode field in the database and just set it to NULL. The schema won&amp;#39;t be rebuilt, but it will stop attempting to rebuild it and the groups will load.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;br /&gt;&lt;font size="4"&gt;&lt;span style="font-weight:bold;"&gt;Conclusion&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;Well, there you have it. Of course, I could have just told you the problem and provide the fix. But that isn&amp;#39;t &lt;span style="font-style:italic;"&gt;really&lt;/span&gt; what this post is about (well it is, but there is more). This post was really more of an exercise in troubleshooting. That&amp;#39;s the most difficult part of working with SalesLogix Web some times. Just knowing where to look and what to look for when an issue creeps in.&lt;br /&gt;&lt;/p&gt;&lt;img src="http://customerfx.com/aggbug.aspx?PostID=40820" width="1" height="1"&gt;</content><author><name>Ryan Farley</name><uri>http://customerfx.com/members/Ryan-Farley.aspx</uri></author><category term="Issues and Bugs" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Issues+and+Bugs/default.aspx" /><category term="SalesLogix Web" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/SalesLogix+Web/default.aspx" /><category term="Troubleshooting" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Troubleshooting/default.aspx" /><category term="SalesLogix 7.5" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/SalesLogix+7.5/default.aspx" /><category term="Tools" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Tools/default.aspx" /></entry><entry><title>Determining if a User Has Read or Write Access to a Field in SalesLogix Web</title><link rel="alternate" type="text/html" href="http://customerfx.com/pages/crmdeveloper/2009/07/23/determining-if-a-user-has-read-or-write-access-to-a-field-in-saleslogix-web.aspx" /><id>http://customerfx.com/pages/crmdeveloper/2009/07/23/determining-if-a-user-has-read-or-write-access-to-a-field-in-saleslogix-web.aspx</id><published>2009-07-23T23:28:00Z</published><updated>2009-07-23T23:28:00Z</updated><content type="html">
&lt;p&gt;It is useful at times to be able to programatically determine at runtime if a user has read access, write access, or no access to a particular field at runtime. There are many different ways this information can be used to ensure you&amp;#39;re giving the current user the best, and most understandable experience based on that particular user&amp;#39;s security settings allow for. Luckily, with the introduction of the FieldLevelSecurityService in SalesLogix 7.5 this is an easy task. Let&amp;#39;s take a look.&lt;/p&gt;

&lt;p&gt;Let&amp;#39;s say for this example, you want to check the current user&amp;#39;s access level to the &amp;quot;AccountName&amp;quot; property on the Account entity. We&amp;#39;ll do this in a Code Snippet Action, so we&amp;#39;ll be passed a reference to the current form (let&amp;#39;s assume we&amp;#39;re doing this as an action on the AccountDetails form) which will contain a reference to CurrentEntity. The code would look like this:&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre&gt;&lt;span style="color:Green;"&gt;// Assume they can read and write to the field
&lt;/span&gt;Sage.Platform.Security.FieldAccess access &lt;span style="color:Navy;"&gt;=&lt;/span&gt; Sage.Platform.Security.FieldAccess.ReadWrite;
 
&lt;span style="color:Green;"&gt;// Locate the FieldLevelSecurityService 
&lt;/span&gt;Sage.Platform.Security.IFieldLevelSecurityService svc &lt;span style="color:Navy;"&gt;=&lt;/span&gt; ApplicationContext.Current.Services.Get&amp;lt;Sage.Platform.Security.IFieldLevelSecurityService&amp;gt;();   
&lt;span style="color:Blue;"&gt;if&lt;/span&gt; ((svc !&lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;"&gt;null&lt;/span&gt;) 
{
    &lt;span style="color:Green;"&gt;// Check if the current entity is secured
&lt;/span&gt;    &lt;span style="color:Blue;"&gt;if&lt;/span&gt; (svc.EntityIsSecured(form.CurrentEntity.GetType()))
    {
        &lt;span style="color:Green;"&gt;// Use the entity as an IPersistentEntity 
&lt;/span&gt;        Sage.Platform.Orm.Interfaces.IPersistentEntity entity &lt;span style="color:Navy;"&gt;=&lt;/span&gt; form.CurrentEntity as Sage.Platform.Orm.Interfaces.IPersistentEntity;  
        &lt;span style="color:Green;"&gt;// Get the access leve for the AccountName property on the Account entity (current user is built into the check)
&lt;/span&gt;        access &lt;span style="color:Navy;"&gt;=&lt;/span&gt; svc.GetAccessForProperty(entity, &lt;span&gt;&amp;quot;AccountName&amp;quot;&lt;/span&gt;); 
    }
}
 
&lt;span style="color:Green;"&gt;// Now the &amp;#39;access&amp;#39; variable shows their access level
&lt;/span&gt;&lt;span style="color:Blue;"&gt;switch&lt;/span&gt; (access)
{
    &lt;span style="color:Blue;"&gt;case&lt;/span&gt; Sage.Platform.Security.FieldAccess.ReadWrite:
        &lt;span style="color:Green;"&gt;// User has read/write access to Account.AccountName
&lt;/span&gt;        &lt;span style="color:Blue;"&gt;break&lt;/span&gt;;
    &lt;span style="color:Blue;"&gt;case&lt;/span&gt; Sage.Platform.Security.FieldAccess.ReadOnly:
        &lt;span style="color:Green;"&gt;// User has read only access to Account.AccountName
&lt;/span&gt;        &lt;span style="color:Blue;"&gt;break&lt;/span&gt;;
    &lt;span style="color:Blue;"&gt;case&lt;/span&gt; Sage.Platform.Security.FieldAccess.NoAccess:
        &lt;span style="color:Green;"&gt;// User has no access to Account.AccountName
&lt;/span&gt;        &lt;span style="color:Blue;"&gt;break&lt;/span&gt;;
}&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;Ideally you would wrap that up in your own assembly and then reference that as needed. However, there are other ways as well which makes all this even easier. &lt;/p&gt;
&lt;p&gt;Typically, when you use an entity in SalesLogix you reference it via it&amp;#39;s interface. This is a best practice for most cases, however, you can also cast the entity reference to it&amp;#39;s actual implementation type, in this case Sage.SalesLogix.Entities.Account and make for a much easier time and a lot less code. All entities will inherit from Sage.SalesLogix.Orm.EntityBase. The cool part is that EntityBase has a built in method that does the code we did earlier. This method is called GetPropertyAccess. Since the Account (and all entities) inherit from EntityBase, this method comes built in. What all this means is that we can use this implementation instance type and just call that method, passing it the property name (as a string), like this:&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;Sage.SalesLogix.Entities.Account account &lt;span style="color:Navy;"&gt;=&lt;/span&gt; (Sage.SalesLogix.Entities.Account)form.CurrentEntity;  
&lt;span style="color:Blue;"&gt;switch&lt;/span&gt; (account.GetPropertyAccess(&lt;span&gt;&amp;quot;AccountName&amp;quot;&lt;/span&gt;))
{
    &lt;span style="color:Blue;"&gt;case&lt;/span&gt; Sage.Platform.Security.FieldAccess.ReadWrite:
        &lt;span style="color:Green;"&gt;// User has read/write access to Account.AccountName
&lt;/span&gt;        &lt;span style="color:Blue;"&gt;break&lt;/span&gt;;
    &lt;span style="color:Blue;"&gt;case&lt;/span&gt; Sage.Platform.Security.FieldAccess.ReadOnly:
        &lt;span style="color:Green;"&gt;// User has read only access to Account.AccountName
&lt;/span&gt;        &lt;span style="color:Blue;"&gt;break&lt;/span&gt;;
    &lt;span style="color:Blue;"&gt;case&lt;/span&gt; Sage.Platform.Security.FieldAccess.NoAccess:
        &lt;span style="color:Green;"&gt;// User has no access to Account.AccountName
&lt;/span&gt;        &lt;span style="color:Blue;"&gt;break&lt;/span&gt;;
}&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;That is much easier and much cleaner, but knowing what that method does exactly makes things more flexible for you so you can do this with or without using the actual entity type and just stick to using the interface. &lt;br /&gt;&lt;/p&gt;
&lt;img src="http://customerfx.com/aggbug.aspx?PostID=40715" width="1" height="1"&gt;</content><author><name>Ryan Farley</name><uri>http://customerfx.com/members/Ryan-Farley.aspx</uri></author><category term="SDK Development" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/SDK+Development/default.aspx" /><category term="SalesLogix Web" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/SalesLogix+Web/default.aspx" /><category term="SalesLogix 7.5" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/SalesLogix+7.5/default.aspx" /><category term="EntityFactory" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/EntityFactory/default.aspx" /></entry><entry><title>Creating Modules for SalesLogix Web and Hiding Toolbar Items at Runtime</title><link rel="alternate" type="text/html" href="http://customerfx.com/pages/crmdeveloper/2009/07/15/creating-modules-for-saleslogix-web-and-hiding-toolbar-items-at-runtime.aspx" /><link rel="enclosure" type="application/x-zip-compressed" length="3644" href="http://customerfx.com/pages/crmdeveloper/attachment/40688.ashx" /><id>http://customerfx.com/pages/crmdeveloper/2009/07/15/creating-modules-for-saleslogix-web-and-hiding-toolbar-items-at-runtime.aspx</id><published>2009-07-15T21:31:00Z</published><updated>2009-07-15T21:31:00Z</updated><content type="html">
&lt;p&gt;Creating modules for SalesLogix Web is something that is likely something that is often overlooked or not used because they are assumed to be too complex or are just not understood. A module is an assembly that you&amp;#39;ve added to a page or the portal that adds functionality to the page. The great thing about a module is that you can change things about the page without needing to resort to doing something like modifying the deployed pages or SmartParts. This article will look at how to create a module to conditionally hide a menu item at runtime.&lt;/p&gt;

&lt;p style="margin-left:40px;"&gt;&lt;span style="font-style:italic;"&gt;Note: In this article I will be creating a module that removes the &amp;quot;Import Leads&amp;quot; menu for users that are not on the Midwest team.&lt;/span&gt; &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;To create a module, you simply just need to create a new Class Library project in Visual Studio and reference some of the Sage DLLs. The main ones you&amp;#39;ll likely need referenced are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sage.Platform.dll&lt;/li&gt;

&lt;li&gt;Sage.Platform.Application.dll&lt;/li&gt;

&lt;li&gt;Microsoft.Practices.ObjectBuilder.dll&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
There will be other DLLs that you&amp;#39;ll likely need to reference as well depending on what exactly you&amp;#39;re doing in the module. The sample module in this post does include many others. &lt;span style="font-style:italic;font-weight:bold;"&gt;The main thing is that your class in the DLL will need to implement the IModule interface from Sage.Platform.Application.dll&lt;/span&gt;.&lt;br /&gt;
&lt;p&gt;When you implement the IModule interface, there are two things you must implement. The void Load method and a ModuleWorkItem get property returning a WorkItem. The shell of your module will look something like this:&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre&gt;&lt;span style="color:Blue;"&gt;namespace&lt;/span&gt; FX.Modules&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;class&lt;/span&gt; LeadMenuModule : Sage.Platform.Application.IModule&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;void&lt;/span&gt; Load()&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color:Green;"&gt;// implement load code here &lt;br /&gt;&lt;/span&gt;        }&lt;br /&gt;        &lt;span style="color:Blue;"&gt;public&lt;/span&gt; WorkItem ModuleWorkItem&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color:Blue;"&gt;get&lt;/span&gt; { &lt;span style="color:Blue;"&gt;return&lt;/span&gt; &lt;span style="color:Blue;"&gt;null&lt;/span&gt;; }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;Now we&amp;#39;ll need to add the code into our Load to do the work of checking to see the teams the user is on, and if not on the Midwest team to remove the menu item. However, in order to do that, we&amp;#39;ll need to access some of the available services for things like getting the parent WorkItem, using the UserService to get the current user, and so forth. We can easily get the references through dependency injection by adding the following to our class:&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre&gt;&lt;span style="color:Blue;"&gt;using&lt;/span&gt; Sage.Platform.Application;&lt;br /&gt;&lt;span style="color:Blue;"&gt;using&lt;/span&gt; Sage.Platform.Security;&lt;br /&gt;&lt;span style="color:Green;"&gt;//...&lt;br /&gt;&lt;/span&gt; &lt;br /&gt;&lt;span style="color:Blue;"&gt;private&lt;/span&gt; UIWorkItem _parentWorkItem;&lt;br /&gt;[ServiceDependency(Type=typeof(WorkItem))]&lt;br /&gt;&lt;span style="color:Blue;"&gt;public&lt;/span&gt; UIWorkItem ParentWorkItem&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:Blue;"&gt;get&lt;/span&gt; { &lt;span style="color:Blue;"&gt;return&lt;/span&gt; _parentWorkItem; }&lt;br /&gt;    &lt;span style="color:Blue;"&gt;set&lt;/span&gt; { _parentWorkItem &lt;span style="color:Navy;"&gt;=&lt;/span&gt; value; }&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;&lt;span style="color:Blue;"&gt;private&lt;/span&gt; IUserService _userService;&lt;br /&gt;[ServiceDependency]&lt;br /&gt;&lt;span style="color:Blue;"&gt;public&lt;/span&gt; IUserService UserService&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:Blue;"&gt;set&lt;/span&gt; { _userService &lt;span style="color:Navy;"&gt;=&lt;/span&gt; value; }&lt;br /&gt;    &lt;span style="color:Blue;"&gt;get&lt;/span&gt; { &lt;span style="color:Blue;"&gt;return&lt;/span&gt; _userService; }&lt;br /&gt;}&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;Having those dependencies will make the work easy from here on out. One of the things we&amp;#39;ll need is to determine if the user is on a certain team or not as well. We can reference one of my earlier posts to determine that (See &lt;a href="http://customerfx.com/pages/crmdeveloper/2009/02/04/determining-if-a-user-is-a-member-of-a-team-in-saleslogix-web.aspx"&gt;Determining if a User is a Member of a Team in SalesLogix Web&lt;/a&gt;).&lt;/p&gt;

&lt;p style="font-weight:bold;"&gt;Removing the Menu Item at Runtime&lt;/p&gt;

&lt;p&gt;Before we look at the code altogether, let&amp;#39;s take a look at how to remove the menu item at runtime. It is easy enough to do now that we&amp;#39;ll have a reference to the page Work Item.&lt;br /&gt;&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre&gt;&lt;span style="color:Blue;"&gt;using&lt;/span&gt; Sage.Platform.WebPortal.Workspaces;&lt;br /&gt;&lt;span style="color:Blue;"&gt;using&lt;/span&gt; Sage.Platform.WebPortal.Services;&lt;br /&gt;&lt;span style="color:Blue;"&gt;using&lt;/span&gt; Sage.Platform.WebPortal.SmartParts;&lt;br /&gt;&lt;span style="color:Green;"&gt;//...&lt;br /&gt;&lt;/span&gt; &lt;br /&gt;&lt;span style="color:Green;"&gt;// Get the ToolbarWorkspace&lt;br /&gt;&lt;/span&gt;ToolbarWorkspace toolbar &lt;span style="color:Navy;"&gt;=&lt;/span&gt; _parentWorkItem.Workspaces[&lt;span&gt;&amp;quot;ToolBar&amp;quot;&lt;/span&gt;] as ToolbarWorkspace;&lt;br /&gt; &lt;br /&gt;&lt;span style="color:Green;"&gt;// Get the MenuService for the ToolbarWorkspace&lt;br /&gt;&lt;/span&gt;IMenuService menusvc &lt;span style="color:Navy;"&gt;=&lt;/span&gt; toolbar.WorkItem.Services.Get&amp;lt;IMenuService&amp;gt;();&lt;br /&gt; &lt;br /&gt;&lt;span style="color:Green;"&gt;// Find the &amp;quot;Tools&amp;quot; menu by it&amp;#39;s ID &lt;br /&gt;&lt;/span&gt;NavItemCollection navcol &lt;span style="color:Navy;"&gt;=&lt;/span&gt; menusvc.FindMenu(&lt;span&gt;&amp;quot;mnuTools&amp;quot;&lt;/span&gt;) as NavItemCollection;&lt;br /&gt;&lt;span style="color:Blue;"&gt;if&lt;/span&gt; (navcol !&lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;"&gt;null&lt;/span&gt;)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:Green;"&gt;// Remove the &amp;quot;Import Leads&amp;quot; menu by using it&amp;#39;s ID &lt;br /&gt;&lt;/span&gt;    navcol.RemoveItem(&lt;span&gt;&amp;quot;tools_ImportLeads&amp;quot;&lt;/span&gt;);&lt;br /&gt;}&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;One thing to note is that if you look at a deployed page, such as the Account.aspx.cs file, you&amp;#39;ll see that in the Page_Load, the menu&amp;#39;s are constructed *before* the modules are loaded. So, when our module is added to the page, the menus will be loaded and ready for us. &lt;/p&gt;

&lt;p&gt;Now, let&amp;#39;s see the complete code for the module:&lt;/p&gt;


&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre&gt;&lt;span style="color:Blue;"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color:Blue;"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;br /&gt;&lt;span style="color:Blue;"&gt;using&lt;/span&gt; Sage.Platform.Application;&lt;br /&gt;&lt;span style="color:Blue;"&gt;using&lt;/span&gt; Sage.Platform.Application.UI;&lt;br /&gt;&lt;span style="color:Blue;"&gt;using&lt;/span&gt; Sage.Platform.WebPortal.Services;&lt;br /&gt;&lt;span style="color:Blue;"&gt;using&lt;/span&gt; Sage.Platform.WebPortal.Workspaces;&lt;br /&gt;&lt;span style="color:Blue;"&gt;using&lt;/span&gt; Sage.Platform.WebPortal.SmartParts;&lt;br /&gt;&lt;span style="color:Blue;"&gt;using&lt;/span&gt; Sage.Platform.Security;&lt;br /&gt;&lt;span style="color:Blue;"&gt;using&lt;/span&gt; Sage.SalesLogix.Security;&lt;br /&gt; &lt;br /&gt;&lt;span style="color:Blue;"&gt;namespace&lt;/span&gt; FX.Modules&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;class&lt;/span&gt; LeadMenuModule : Sage.Platform.Application.IModule&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;void&lt;/span&gt; Load()&lt;br /&gt;        {&lt;br /&gt;            User user &lt;span style="color:Navy;"&gt;=&lt;/span&gt; (_userService as SLXUserService).GetUser();&lt;br /&gt;            &lt;span style="color:Blue;"&gt;if&lt;/span&gt; (user.Id.ToLower().Trim()==&lt;span&gt;&amp;quot;admin&amp;quot;&lt;/span&gt;) &lt;span style="color:Blue;"&gt;return&lt;/span&gt;;&lt;br /&gt;            &lt;span style="color:Blue;"&gt;if&lt;/span&gt; (!IsOnTeam(&lt;span&gt;&amp;quot;Midwest&amp;quot;&lt;/span&gt;, user))&lt;br /&gt;            {&lt;br /&gt;                ToolbarWorkspace toolbar &lt;span style="color:Navy;"&gt;=&lt;/span&gt; _parentWorkItem.Workspaces[&lt;span&gt;&amp;quot;ToolBar&amp;quot;&lt;/span&gt;] as ToolbarWorkspace;&lt;br /&gt;                IMenuService menusvc &lt;span style="color:Navy;"&gt;=&lt;/span&gt; toolbar.WorkItem.Services.Get&amp;lt;IMenuService&amp;gt;();&lt;br /&gt;                NavItemCollection navcol &lt;span style="color:Navy;"&gt;=&lt;/span&gt; menusvc.FindMenu(&lt;span&gt;&amp;quot;mnuTools&amp;quot;&lt;/span&gt;) as NavItemCollection;&lt;br /&gt;                &lt;span style="color:Blue;"&gt;if&lt;/span&gt; (navcol !&lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;"&gt;null&lt;/span&gt;)&lt;br /&gt;                {&lt;br /&gt;                    navcol.RemoveItem(&lt;span&gt;&amp;quot;tools_ImportLeads&amp;quot;&lt;/span&gt;);&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;bool&lt;/span&gt; IsOnTeam(&lt;span style="color:Blue;"&gt;string&lt;/span&gt; teamname, User user)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color:Blue;"&gt;bool&lt;/span&gt; res &lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;"&gt;false&lt;/span&gt;;&lt;br /&gt;            IList&amp;lt;Owner&amp;gt; teams &lt;span style="color:Navy;"&gt;=&lt;/span&gt; Owner.GetTeamsByUser(user);&lt;br /&gt;            &lt;span style="color:Blue;"&gt;foreach&lt;/span&gt; (Owner team &lt;span style="color:Blue;"&gt;in&lt;/span&gt; teams)&lt;br /&gt;            {&lt;br /&gt;                &lt;span style="color:Blue;"&gt;if&lt;/span&gt; (team.OwnerDescription.ToLower().Equals(teamname.ToLower()))&lt;br /&gt;                {&lt;br /&gt;                    res &lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;"&gt;true&lt;/span&gt;;&lt;br /&gt;                    &lt;span style="color:Blue;"&gt;break&lt;/span&gt;;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            &lt;span style="color:Blue;"&gt;return&lt;/span&gt; res;&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color:Blue;"&gt;public&lt;/span&gt; WorkItem ModuleWorkItem&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color:Blue;"&gt;get&lt;/span&gt; { &lt;span style="color:Blue;"&gt;return&lt;/span&gt; &lt;span style="color:Blue;"&gt;null&lt;/span&gt;; }&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color:Blue;"&gt;private&lt;/span&gt; UIWorkItem _parentWorkItem;&lt;br /&gt;        [ServiceDependency(Type=typeof(WorkItem))]&lt;br /&gt;        &lt;span style="color:Blue;"&gt;public&lt;/span&gt; UIWorkItem ParentWorkItem&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color:Blue;"&gt;get&lt;/span&gt; { &lt;span style="color:Blue;"&gt;return&lt;/span&gt; _parentWorkItem; }&lt;br /&gt;            &lt;span style="color:Blue;"&gt;set&lt;/span&gt; { _parentWorkItem &lt;span style="color:Navy;"&gt;=&lt;/span&gt; value; }&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color:Blue;"&gt;private&lt;/span&gt; IUserService _userService;&lt;br /&gt;        [ServiceDependency]&lt;br /&gt;        &lt;span style="color:Blue;"&gt;public&lt;/span&gt; IUserService UserService&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color:Blue;"&gt;set&lt;/span&gt; { _userService &lt;span style="color:Navy;"&gt;=&lt;/span&gt; value; }&lt;br /&gt;            &lt;span style="color:Blue;"&gt;get&lt;/span&gt; { &lt;span style="color:Blue;"&gt;return&lt;/span&gt; _userService; }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;


&lt;p&gt;Not too bad. It made fairly easy work to get the job done. Now we just add this assembly into the &amp;quot;bin&amp;quot; folder in the Support Files for the portal and then add the module in to the &amp;quot;Modules&amp;quot; tabs of the portal itself (not to a specific page) and the code will apply throughout the entire portal. On any page the user visits, the code will ensure the Import Leads menu item is removed.&lt;/p&gt;
&lt;p&gt;Note, we could make this even more generic if we wanted to. Let&amp;#39;s say we didn&amp;#39;t want to hard-code the team name, or the menu item ID. We could simple add some properties to the class like this:&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;span style="color:Blue;"&gt;public&lt;/span&gt; TeamName { &lt;span style="color:Blue;"&gt;get&lt;/span&gt;; &lt;span style="color:Blue;"&gt;set&lt;/span&gt;; }&lt;br /&gt;&lt;span style="color:Blue;"&gt;public&lt;/span&gt; MenuItemID { &lt;span style="color:Blue;"&gt;get&lt;/span&gt;; &lt;span style="color:Blue;"&gt;set&lt;/span&gt;; }&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;Now, when we add it to the portal we can click the &amp;quot;Configure&amp;quot; button next to it on the Modules tab and we&amp;#39;ll see our properties for &amp;quot;TeamName and MenuItemID. We&amp;#39;d change the code to use those property values, instead of the hard coded ones, and then the administrator could simply use the Configure button to see the properties listed and enter the TeamName and MenuItemID to remove for anyone not on that team. Then a redeploy and the changes are live. Now you can change the values easily, without touching the code, or even reuse the module for something else.&lt;/p&gt;&lt;p&gt;If you want to take a look at the completed DLL (with the hard coded values), I&amp;#39;ve attached the Visual Studio project to this post (it will look for the references Sage DLLs in the usual Copy Assemblies location C:\Program Files\SalesLogix\ReferenceAssemblies).&lt;/p&gt;&lt;img src="http://customerfx.com/aggbug.aspx?PostID=40688" width="1" height="1"&gt;</content><author><name>Ryan Farley</name><uri>http://customerfx.com/members/Ryan-Farley.aspx</uri></author><category term="Development" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Development/default.aspx" /><category term="New Finds" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/New+Finds/default.aspx" /><category term="SalesLogix Web" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/SalesLogix+Web/default.aspx" /><category term="Modules" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Modules/default.aspx" /></entry><entry><title>Extracting Reports from the SalesLogix Plugin Table from External Applications</title><link rel="alternate" type="text/html" href="http://customerfx.com/pages/crmdeveloper/2009/05/29/extracting-reports-from-the-saleslogix-plugin-table-from-external-applications.aspx" /><id>http://customerfx.com/pages/crmdeveloper/2009/05/29/extracting-reports-from-the-saleslogix-plugin-table-from-external-applications.aspx</id><published>2009-05-29T20:09:00Z</published><updated>2009-05-29T20:09:00Z</updated><content type="html">&lt;p&gt;There are many reasons why extracting a SalesLogix Report from the SalesLogix database might be useful. There are possibilities of integration, automated running of reports, as well as the need to generate a PDF from some code on a server using a SalesLogix Crystal report.&lt;/p&gt;
&lt;p&gt;SalesLogix stores reports in the DATA field, which is a binary (BLOB) field in the PLUGIN table. Not just the report, but the SalesLogix report &lt;i&gt;plugin&lt;/i&gt;, which contains not only the report itself but also the plugin info for the report. All together in a single BLOB field. This BLOB field is the serialized Delphi class named TCRWReportWrapper with the report file bytes appended to the end of the serialized class bytes. &lt;/p&gt;
&lt;p&gt;Luckily, a serialized Delphi class will always end in two consecutive NULL bytes (0x00, 0x00) and will never contain two consecutive NULL bytes internally. This makes out job a bit easier in knowing where the serialized Delphi class ends and the bytes making up the report file begin. We can read out the bytes from PLUGIN.DATA for the report record and then read through them until we find the two consecutive NULL bytes, when write out everything following to a file and we&amp;#39;ll have the report itself.&lt;/p&gt;
&lt;p&gt;Here is some C# code to do just that:&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;span style="color:Blue;"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color:Blue;"&gt;using&lt;/span&gt; System.Data;&lt;br /&gt;&lt;span style="color:Blue;"&gt;using&lt;/span&gt; System.Data.OleDb;&lt;br /&gt;&lt;span style="color:Blue;"&gt;using&lt;/span&gt; System.IO;&lt;br /&gt; &lt;br /&gt;&lt;span style="color:Blue;"&gt;namespace&lt;/span&gt; FX.SalesLogix.Utility&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;class&lt;/span&gt; ReportExtractor&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:Blue;"&gt;public&lt;/span&gt; ReportExtractor(&lt;span style="color:Blue;"&gt;string&lt;/span&gt; ConnectionString)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color:Blue;"&gt;this&lt;/span&gt;.ConnectionString &lt;span style="color:Navy;"&gt;=&lt;/span&gt; ConnectionString;&lt;br /&gt;        }&lt;br /&gt; &lt;br /&gt;        &lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;string&lt;/span&gt; ConnectionString { &lt;span style="color:Blue;"&gt;get&lt;/span&gt;; &lt;span style="color:Blue;"&gt;set&lt;/span&gt;; }&lt;br /&gt; &lt;br /&gt;        &lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;void&lt;/span&gt; GetReport(&lt;span style="color:Blue;"&gt;string&lt;/span&gt; PluginID, &lt;span style="color:Blue;"&gt;string&lt;/span&gt; DestinationFile)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color:Blue;"&gt;using&lt;/span&gt; (OleDbConnection conn &lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; OleDbConnection(&lt;span style="color:Blue;"&gt;this&lt;/span&gt;.ConnectionString))&lt;br /&gt;            {&lt;br /&gt;                conn.Open();&lt;br /&gt;                &lt;span style="color:Blue;"&gt;using&lt;/span&gt; (OleDbCommand cmd &lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; OleDbCommand(&lt;span&gt;&amp;quot;SELECT DATA FROM PLUGIN WHERE PLUGINID = ?&amp;quot;&lt;/span&gt;, conn))&lt;br /&gt;                {&lt;br /&gt;                    cmd.Parameters.Add(&lt;span style="color:Blue;"&gt;new&lt;/span&gt; OleDbParameter(&lt;span&gt;&amp;quot;PLUGINID&amp;quot;&lt;/span&gt;, PluginID));&lt;br /&gt; &lt;br /&gt;                    &lt;span style="color:Green;"&gt;// Get the plugin byte array&lt;br /&gt;&lt;/span&gt;                    byte[] data &lt;span style="color:Navy;"&gt;=&lt;/span&gt; (byte[])cmd.ExecuteScalar();&lt;br /&gt;&lt;br /&gt;                    &lt;span style="color:Green;"&gt;// Look for the two consecutive null bytes&lt;br /&gt;&lt;/span&gt;                    &lt;span style="color:Blue;"&gt;int&lt;/span&gt; idx &lt;span style="color:Navy;"&gt;=&lt;/span&gt; 0;&lt;br /&gt;                    &lt;span style="color:Blue;"&gt;for&lt;/span&gt; (&lt;span style="color:Blue;"&gt;int&lt;/span&gt; i &lt;span style="color:Navy;"&gt;=&lt;/span&gt; 0; i &amp;lt; data.Length; i++)&lt;br /&gt;                    {&lt;br /&gt;                        &lt;span style="color:Blue;"&gt;if&lt;/span&gt; ((&lt;span style="color:Blue;"&gt;int&lt;/span&gt;)data[ i ] == 0 &amp;amp;&amp;amp; (&lt;span style="color:Blue;"&gt;int&lt;/span&gt;)data[i &lt;span style="color:Navy;"&gt;+&lt;/span&gt; 1] == 0)&lt;br /&gt;                        {&lt;br /&gt;                            idx &lt;span style="color:Navy;"&gt;=&lt;/span&gt; i &lt;span style="color:Navy;"&gt;+&lt;/span&gt; 2;&lt;br /&gt;                            &lt;span style="color:Blue;"&gt;break&lt;/span&gt;;&lt;br /&gt;                        }&lt;br /&gt;                    }&lt;br /&gt; &lt;br /&gt;                    &lt;span style="color:Green;"&gt;// Get everything after the two consecutive bytes&lt;br /&gt;&lt;/span&gt;                    byte[] rpt &lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; byte[data.Length];&lt;br /&gt;                    Array.Copy(data, idx, rpt, 0, data.Length &lt;span style="color:Navy;"&gt;-&lt;/span&gt; idx);&lt;br /&gt; &lt;br /&gt;                    &lt;span style="color:Green;"&gt;// Write out to an RPT file &lt;br /&gt;&lt;/span&gt;                    &lt;span style="color:Blue;"&gt;using&lt;/span&gt; (FileStream f &lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; FileStream(DestinationFile, FileMode.CreateNew))&lt;br /&gt;                    {&lt;br /&gt;                        f.Write(rpt, 0, rpt.Length);&lt;br /&gt;                        f.Close();&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;To use the code you&amp;#39;d do something like the following:&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;span style="color:Green;"&gt;// Extract report to C:\MyReportFile.rpt&lt;br /&gt;&lt;/span&gt;ReportExtractor rptextractor &lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; ReportExtractor(MyConnectionString);&lt;br /&gt;rptextractor.GetReport(&lt;span&gt;&amp;quot;pDEMOA0000HQ&amp;quot;&lt;/span&gt;, &lt;span&gt;@&amp;quot;C:\MyReportFile.rpt&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;Now you can do whatever you&amp;#39;d like with the report such as open it in an RDC object and generate a PDF from it. &lt;br /&gt;&lt;/p&gt;
&lt;img src="http://customerfx.com/aggbug.aspx?PostID=40572" width="1" height="1"&gt;</content><author><name>Ryan Farley</name><uri>http://customerfx.com/members/Ryan-Farley.aspx</uri></author><category term="Development" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Development/default.aspx" /><category term="SalesLogix" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/SalesLogix/default.aspx" /><category term="C#" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/C_2300_/default.aspx" /></entry><entry><title>Determining the Page Mode at Runtime in SalesLogix Web</title><link rel="alternate" type="text/html" href="http://customerfx.com/pages/crmdeveloper/2009/04/20/determining-the-page-mode-at-runtime-in-saleslogix-web.aspx" /><id>http://customerfx.com/pages/crmdeveloper/2009/04/20/determining-the-page-mode-at-runtime-in-saleslogix-web.aspx</id><published>2009-04-20T18:42:00Z</published><updated>2009-04-20T18:42:00Z</updated><content type="html">&lt;p&gt;One of the keys to reusing a form for both inserting new records and displaying existing record detail is the ability to determine if the form is currently in insert mode or detail mode. There are several ways to determine this at runtime so you can take the necessary steps depeding on the current form mode.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;b&gt;&lt;i&gt;Out of the box, there are three defined form types: Detail, Insert, &amp;amp; List&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Some of the code we&amp;#39;ll use will differ whether you&amp;#39;re using a C# Snippet Action (where the code is added to the form itself) or a Code Snippet Action (where the code is added to a separate assembly and you&amp;#39;re passed an adapter object to access limited form properties).&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;font size="4"&gt;&lt;b&gt;From a C# Snippet Action &lt;/b&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;Use the following code to access the exposed EntityForm property of the form and determine the form mode.&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre&gt;&lt;span style="color:Blue;"&gt;if&lt;/span&gt; (EntityPage.IsInsertMode)&lt;br /&gt;    labelMode.Text &lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;span&gt;&amp;quot;Insert Mode&amp;quot;&lt;/span&gt;;&lt;br /&gt;&lt;span style="color:Blue;"&gt;else&lt;/span&gt;&lt;br /&gt;    labelMode.Text &lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;span&gt;&amp;quot;Not insert mode&amp;quot;&lt;/span&gt;;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;span style="color:Green;"&gt;// or&lt;br /&gt;&lt;/span&gt; &lt;br /&gt; &lt;br /&gt;&lt;span style="color:Blue;"&gt;if&lt;/span&gt; (EntityPage.ViewMode == Sage.Platform.Orm.Entities.EntityViewMode.Insert)&lt;br /&gt;    labelMode.Text &lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;span&gt;&amp;quot;Insert Mode&amp;quot;&lt;/span&gt;;&lt;br /&gt;&lt;span style="color:Blue;"&gt;else&lt;/span&gt;&lt;br /&gt;    labelMode.Text &lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;span&gt;&amp;quot;Not insert mode&amp;quot;&lt;/span&gt;;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;


&lt;p&gt;&lt;br /&gt;&lt;font size="4"&gt;&lt;b&gt;From a Code Snippet Action&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;For a Code Snippet Action, you&amp;#39;ll need to do things a little differently. In a Code Snippet Action you&amp;#39;re only passed an adapter, or a wrapper, for the form, not the form itself. So, the problem is that you cannot access the page&amp;#39;s EntityPage reference. You can still get to it however, you&amp;#39;ll just have a few extra steps to dig through. Luckily, the form adapter exposes the SmartPart via the NativeForm property.&lt;br /&gt;&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre&gt;&lt;span style="color:Green;"&gt;// First get a reference to the underlying SmartPart itself&lt;br /&gt;&lt;/span&gt;Sage.Platform.WebPortal.SmartParts.SmartPart smartpart &lt;span style="color:Navy;"&gt;=&lt;/span&gt; form.NativeForm as Sage.Platform.WebPortal.SmartParts.SmartPart;&lt;br /&gt;&lt;span style="color:Green;"&gt;// Now get the SmartPart&amp;#39;s parent page and use it as an EntityPage&lt;br /&gt;&lt;/span&gt;Sage.Platform.WebPortal.EntityPage page &lt;span style="color:Navy;"&gt;=&lt;/span&gt; smartpart.Page as Sage.Platform.WebPortal.EntityPage;&lt;br /&gt;&lt;span style="color:Green;"&gt;// Now you can proceed as normal...&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:Blue;"&gt;if&lt;/span&gt; (page.IsInsertMode)&lt;br /&gt;    form.labelMode.Text &lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;span&gt;&amp;quot;Insert Mode&amp;quot;&lt;/span&gt;;&lt;br /&gt;&lt;span style="color:Blue;"&gt;else&lt;/span&gt;&lt;br /&gt;    form.labelMode.Text &lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;span&gt;&amp;quot;Not insert mode&amp;quot;&lt;/span&gt;;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;span style="color:Green;"&gt;// or&lt;br /&gt;&lt;/span&gt; &lt;br /&gt; &lt;br /&gt;&lt;span style="color:Blue;"&gt;if&lt;/span&gt; (page.ViewMode == Sage.Platform.Orm.Entities.EntityViewMode.Insert)&lt;br /&gt;    form.labelMode.Text &lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;span&gt;&amp;quot;Insert Mode&amp;quot;&lt;/span&gt;;&lt;br /&gt;&lt;span style="color:Blue;"&gt;else&lt;/span&gt;&lt;br /&gt;    form.labelMode.Text &lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;span&gt;&amp;quot;Not insert mode&amp;quot;&lt;/span&gt;;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;&amp;nbsp;&lt;br /&gt;&lt;font size="4"&gt;&lt;b&gt;Checking the Entity&amp;#39;s ID Property&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;One last way you can use to check to see if the page is in Insert mode is to check the entity&amp;#39;s Id property. If it is null then you have a new entity, not yet persisted to the database.&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;span style="color:Blue;"&gt;if&lt;/span&gt; (myentity.Id == &lt;span style="color:Blue;"&gt;null&lt;/span&gt;)&lt;br /&gt;    &lt;span style="color:Green;"&gt;// this is a new entity&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;The problem is that it is possible that this won&amp;#39;t infer the correct mode. That is telling you that the object hasn&amp;#39;t yet been persisted to the database, which might be enough, but you might want different behavior for new objects on the form vs the form being in insert mode itself. Just make sure that if you use this method to determine the page mode that you understand the differences so you know what you&amp;#39;re really checking.&lt;br /&gt;&lt;/p&gt;
&lt;img src="http://customerfx.com/aggbug.aspx?PostID=40457" width="1" height="1"&gt;</content><author><name>Ryan Farley</name><uri>http://customerfx.com/members/Ryan-Farley.aspx</uri></author><category term="SalesLogix Web" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/SalesLogix+Web/default.aspx" /><category term="Entity Model" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Entity+Model/default.aspx" /><category term="SmartParts" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/SmartParts/default.aspx" /><category term="Quick Forms" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Quick+Forms/default.aspx" /></entry><entry><title>Accessing the Current Parent Entity from a Code Snippet Action</title><link rel="alternate" type="text/html" href="http://customerfx.com/pages/crmdeveloper/2009/04/08/accessing-the-current-parent-entity-from-a-code-snippet-action.aspx" /><id>http://customerfx.com/pages/crmdeveloper/2009/04/08/accessing-the-current-parent-entity-from-a-code-snippet-action.aspx</id><published>2009-04-08T15:00:00Z</published><updated>2009-04-08T15:00:00Z</updated><content type="html">
&lt;p&gt;The transition from using pre-version 7.5.1 &amp;quot;C# Snippet Actions&amp;quot;, where the code is placed inline in the form, and the new &amp;quot;Code Snippet Actions&amp;quot;, where the code is compiled into a separate DLL and a psudo-form reference is passed in, can be frustrating at times. I ran into yet another instance of that today. Before, we were spoiled using the C# Snippet Actions. We had access to everything on the form. Everything. That&amp;#39;s no longer the case with Code Snippet Actions. While in a Code Snippet Action, I needed a reference to the current parent entity (not the current entity that is exposed via form.CurrentEntity, but it&amp;#39;s parent). This Code Snippet Action was on a LoadAction of an Insert screen so the parent had not yet been set. Let&amp;#39;s take a look at how to solve that.&lt;/p&gt;

&lt;p&gt;Before you go on, read a previous post of mine where I discuss the differences between C# Snippet Actions and Code Snippet Actions if you&amp;#39;ve not done so already: &lt;a href="http://customerfx.com/pages/crmdeveloper/2009/03/26/setting-the-default-sort-for-a-datagrid-in-saleslogix-web-revisited.aspx"&gt;Setting the Default Sort for a DataGrid in SalesLogix Web REVISITED&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;font size="4"&gt;&lt;b&gt;The Problem &lt;/b&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;The problem I needed to solve was get the current entity&amp;#39;s parent from a LoadAction on an insert screen. At that time the parent had not yet been set so we couldn&amp;#39;t just use myentity.ParentEntity to get it. If this were an older C# Snippet Action then I could have simply used the following:&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre&gt;IMyParentEntity myparent &lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;"&gt;this&lt;/span&gt;.GetParentEntity() as IMyParentEntity;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;That would have been great. But this wasn&amp;#39;t in a C# Snippet Action and &amp;quot;this&amp;quot; in a Code Snippet Action is an entirely different thing where GetParentEntity did not exist. My first thought was to use the form.NativeForm and cast it as an EntityBoundSmartPart. That seemed logical. The cast worked, however when I attempted to call GetParentEntity it failed due to it&amp;#39;s protection level. Doh! It is protected so I can&amp;#39;t call it from another assembly. &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;font size="4"&gt;&lt;b&gt;The Solution&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;Thankfully, one of the most useful things the form referenced that is passed in has is the page&amp;#39;s WorkItem. Through the WorkItem you can get a reference to one of the many useful services in the portal. In this case, the EntityContextService. The EntityContextService has a method named GetEntity that will give you the currently accessed entity. Not the child entity that my dialog was for, but the entity the page itself is for, my parent entity. I wired up the following code:&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;span style="color:Green;"&gt;// Get a reference to the EntityContextServce&lt;br /&gt;// and call GetEntity() &lt;br /&gt;&lt;/span&gt;IMyParentEntity myparent &lt;span style="color:Navy;"&gt;=&lt;/span&gt; form.WorkItem.Services.Get&amp;lt;Sage.Platform.Application.IEntityContextService&amp;gt;().GetEntity() as IMyParentEntity; &lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;That is it. It works and it isn&amp;#39;t so bad. However, I do miss the C# Snippet Actions as well. I realize I can still use them even though they are marked as obsolete, however, I think there is also value in learning the new way to do things and living with the changes.&lt;br /&gt;&lt;/p&gt;
&lt;img src="http://customerfx.com/aggbug.aspx?PostID=40391" width="1" height="1"&gt;</content><author><name>Ryan Farley</name><uri>http://customerfx.com/members/Ryan-Farley.aspx</uri></author><category term="SalesLogix Web" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/SalesLogix+Web/default.aspx" /><category term="Application Architect" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Application+Architect/default.aspx" /></entry><entry><title>Adding a Default Sort to the Add Opportunity Products List in SalesLogix Web</title><link rel="alternate" type="text/html" href="http://customerfx.com/pages/crmdeveloper/2009/04/07/adding-a-default-sort-to-the-add-opportunity-products-list-in-saleslogix-web.aspx" /><id>http://customerfx.com/pages/crmdeveloper/2009/04/07/adding-a-default-sort-to-the-add-opportunity-products-list-in-saleslogix-web.aspx</id><published>2009-04-07T14:27:00Z</published><updated>2009-04-07T14:27:00Z</updated><content type="html">
&lt;p&gt;Usually by the third time I see a question asked, I realize it needs to be a blog post. I&amp;#39;ve been asked by a couple of customers how to add a default sort to the products list on the Add Opportunity Products form in the SalesLogix Web client. The question of how to add a default sort to the list of products in the Add Opportunity Products form in the web client surfaced again today so I am posting the answer here.&lt;/p&gt;

&lt;p&gt;The approach to sorting the products list on the Add Opportunity products form is different than &lt;a href="http://customerfx.com/pages/crmdeveloper/2009/03/26/setting-the-default-sort-for-a-datagrid-in-saleslogix-web-revisited.aspx"&gt;what I have outlined before for simply sorting a grid&lt;/a&gt;. The opportunity products list is not a DataGrid, but a Tree control. &lt;/p&gt;

&lt;p&gt;&lt;img src="http://customerfx.com/blogs/crmdeveloper/AddOppProduct_ProductsList.png" border="1" alt="" /&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;To sort the products list, instead of telling the control to sort, we will just sort the list of objects that it is bound to. &lt;/p&gt;

&lt;p&gt;First, locate the AddOpportunityProduct SmartMart. This is a custom SmartPart, not a QuickForm, so you won&amp;#39;t find this under the Opportunity entity itself, but instead in the Sage SalesLogix Portal in following location (we&amp;#39;ll just need the code-behind, or &amp;quot;cs&amp;quot; file for this, not the &amp;quot;ascx&amp;quot; file):&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;i&gt;Support Files\SmartParts\Opportunity\AddOpportunityProduct.ascx.cs&lt;/i&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Double-click that file to open it in the Application Architect. In the code, look for the method named &lt;b&gt;GetProductList&lt;/b&gt;. You&amp;#39;ll see the following two lines at the very end of that method:&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre&gt;List&amp;lt;Product&amp;gt; ProductList &lt;span style="color:Navy;"&gt;=&lt;/span&gt; criteriaProduct.List&amp;lt;Product&amp;gt;() as List&amp;lt;Product&amp;gt;;&lt;br /&gt;&lt;span style="color:Blue;"&gt;return&lt;/span&gt; ProductList;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;Right &lt;u&gt;&lt;b&gt;before&lt;/b&gt;&lt;/u&gt; those two lines, add the following line (in this case, we&amp;#39;ll sort the list by family):&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;criteriaProduct.AddOrder(expProduct.Asc(&lt;span&gt;&amp;quot;Family&amp;quot;&lt;/span&gt;));&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;Obviously, you can replace &amp;quot;Family&amp;quot; with any other valid property name on the Opportunity entity to sort the results by. &lt;br /&gt;&lt;/p&gt;
&lt;img src="http://customerfx.com/aggbug.aspx?PostID=40396" width="1" height="1"&gt;</content><author><name>Ryan Farley</name><uri>http://customerfx.com/members/Ryan-Farley.aspx</uri></author><category term="SalesLogix Web" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/SalesLogix+Web/default.aspx" /><category term="Customization" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Customization/default.aspx" /><category term="SmartParts" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/SmartParts/default.aspx" /><category term="Application Architect" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Application+Architect/default.aspx" /></entry><entry><title>Filtering a DataGrid in SalesLogix Web at Runtime</title><link rel="alternate" type="text/html" href="http://customerfx.com/pages/crmdeveloper/2009/04/02/filtering-a-datagrid-in-saleslogix-web-at-runtime.aspx" /><link rel="enclosure" type="application/zip" length="24568" href="http://customerfx.com/pages/crmdeveloper/attachment/40380.ashx" /><id>http://customerfx.com/pages/crmdeveloper/2009/04/02/filtering-a-datagrid-in-saleslogix-web-at-runtime.aspx</id><published>2009-04-02T17:22:00Z</published><updated>2009-04-02T17:22:00Z</updated><content type="html">&lt;p&gt;Binding a DataGrid at runtime is something that many SalesLogix developers are used to doing while working in the LAN client. This task is every bit as easy in the web platform as well. Let&amp;#39;s take a look at how to put this together.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="4"&gt;&lt;b&gt;Scenario&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;For this example, we will put together a tab on the account page. We&amp;#39;ll call this tab &amp;quot;Related Accounts&amp;quot;. It will have a Picklist, showing the Account Types picklist, and a DataGrid. As the user selects an account type value in the picklist we will display all accounts with that account type. Not a really useful customization, but one that will allow us to see how to bind the grid up at runtime using a user selected value.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p style="font-weight:bold;"&gt;&lt;font size="4"&gt;Building the Solution&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;To put this together, let&amp;#39;s start with building a busioness rule that we&amp;#39;ll use to return the data for the grid. You can read more about using GetByMethod to bind a grid to a rule in my previous articles: &lt;a href="http://customerfx.com/pages/crmdeveloper/2008/05/22/creating-a-business-rule-to-return-a-list-of-objects.aspx"&gt;Creating a Business Rule to Return a List of Objects&lt;/a&gt; and &lt;a href="http://customerfx.com/pages/crmdeveloper/2008/05/27/binding-a-grid-to-a-list-returning-business-rule-using-getbymethod.aspx"&gt;Binding a Grid to a List Returning Rule using GetByMethod&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Our business rule will return a list of accounts and will take in one parameter, which will be the user selected account type value. The rule will look like this:&lt;/p&gt;

&lt;p&gt;&lt;span style="font-weight:bold;"&gt;Name:&lt;/span&gt; GetRelatedAccounts&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Return Type:&lt;/span&gt; System.Collections.Generic.IList&amp;lt;Sage.Entity.Interfaces.IAccount&amp;gt;&lt;/p&gt;

&lt;p&gt;Add a parameter as follows (click on the Add link in the Parameters section):&lt;/p&gt;

&lt;p&gt;&lt;span style="font-weight:bold;"&gt;Parameter Name:&lt;/span&gt; TypeValue&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Type:&lt;/span&gt; String&lt;/p&gt;

&lt;p&gt;Now for the code:&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre&gt;&lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;static&lt;/span&gt; &lt;span style="color:Blue;"&gt;void&lt;/span&gt; GetRelatedAccountsStep(IAccount account, &lt;span style="color:Blue;"&gt;string&lt;/span&gt; TypeValue, out System.Collections.Generic.IList&amp;lt;Sage.Entity.Interfaces.IAccount&amp;gt; result)  &lt;br /&gt;{&lt;br /&gt;    IRepository&amp;lt;IAccount&amp;gt; repository &lt;span style="color:Navy;"&gt;=&lt;/span&gt; EntityFactory.GetRepository&amp;lt;IAccount&amp;gt;();&lt;br /&gt;    IQueryable qry &lt;span style="color:Navy;"&gt;=&lt;/span&gt; (IQueryable)repository;&lt;br /&gt;    IExpressionFactory ef &lt;span style="color:Navy;"&gt;=&lt;/span&gt; qry.GetExpressionFactory();&lt;br /&gt;&lt;br /&gt;    ICriteria criteria &lt;span style="color:Navy;"&gt;=&lt;/span&gt; qry.CreateCriteria();&lt;br /&gt;    criteria.Add(ef.Eq(&lt;span&gt;&amp;quot;Type&amp;quot;&lt;/span&gt;, TypeValue));&lt;br /&gt;&lt;br /&gt;    result &lt;span style="color:Navy;"&gt;=&lt;/span&gt; criteria.List&amp;lt;IAccount&amp;gt;();&lt;br /&gt;}&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;Now, we&amp;#39;ll need one more business rule. The SalesLogix DataGrid control itself will throw an error if it does not have a DataSource set at build time. We&amp;#39;re not going to really use the SalesLogix DataSource component at all since we&amp;#39;ll be binding up the grid at runtime. However, it still requires this or it won&amp;#39;t build. To get around this we will have to add a DataSource component to the form as well. Now, we&amp;#39;ll also get errors if we have a DataSource component that is not set to return some data. We can&amp;#39;t use GetByMethod with our new rule we created since our rule takes a param and there is no way to set that for the DataSource. What we will do is create another business rule that returns a blank, empty list of accounts and we&amp;#39;ll use that for the DataSource, just so things compile.&lt;/p&gt;

&lt;p&gt;This is what our empty rule will look like:&lt;/p&gt;

&lt;p&gt;&lt;span style="font-weight:bold;"&gt;Name:&lt;/span&gt; GetEmptyAccountList &lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Return Type:&lt;/span&gt; System.Collections.Generic.IList&amp;lt;Sage.Entity.Interfaces.IAccount&amp;gt;&lt;/p&gt;

&lt;p&gt;The code will be as follows:&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre&gt;&lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;static&lt;/span&gt; &lt;span style="color:Blue;"&gt;void&lt;/span&gt; GetEmptyAccountListStep( IAccount account, out System.Collections.Generic.IList&amp;lt;Sage.Entity.Interfaces.IAccount&amp;gt; result)  &lt;br /&gt;{&lt;br /&gt;    result &lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; System.Collections.Generic.List&amp;lt;IAccount&amp;gt;();&lt;br /&gt;}&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;Now you can use that rule that returns an empty list to set up as the GetByMethod for the DataSource component and then wire the DataSource to the grid. Also throw a Picklist onto the form using the Account Type picklist.&lt;/p&gt;

&lt;p&gt;The picklist will have some code in the OnChange action. Add a &amp;quot;Code Snippet Action&amp;quot; to the OnChange of the Picklist control. The code for that will look as follows:&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;static&lt;/span&gt; &lt;span style="color:Blue;"&gt;void&lt;/span&gt; picklistType_OnChangeStep(IRelatedAccounts form, EventArgs args)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:Green;"&gt;// Get a reference to the underlying ASP.NET GridView control&lt;br /&gt;&lt;/span&gt;    System.Web.UI.WebControls.GridView grid &lt;span style="color:Navy;"&gt;=&lt;/span&gt; (System.Web.UI.WebControls.GridView)form.gridAccounts.NativeControl;  &lt;br /&gt;&lt;br /&gt;    &lt;span style="color:Green;"&gt;// Make sure a value was selected in the Picklist&lt;br /&gt;&lt;/span&gt;    &lt;span style="color:Blue;"&gt;if&lt;/span&gt; (form.picklistType.PickListValue !&lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; form.picklistType.PickListValue !&lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;"&gt;string&lt;/span&gt;.Empty)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:Green;"&gt;// Get a reference to the account and call the rule, passing the picklist value&lt;br /&gt;&lt;/span&gt;        IAccount account &lt;span style="color:Navy;"&gt;=&lt;/span&gt; form.CurrentEntity as IAccount;                &lt;br /&gt;        grid.DataSource &lt;span style="color:Navy;"&gt;=&lt;/span&gt; account.GetRelatedAccounts(form.picklistType.PickListValue);&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color:Blue;"&gt;else&lt;/span&gt;&lt;br /&gt;        grid.DataSource &lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;"&gt;null&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:Green;"&gt;// Call the DataBind method of the GridView to set the binding &lt;br /&gt;&lt;/span&gt;    grid.DataBind();&lt;br /&gt;}&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;That is it. The key is to get a reference to the native underlying ASP.NET GridView control and then do the binding just as you would normally with that control. The end result will look like this:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://customerfx.com/blogs/crmdeveloper/RelatedAccountsScreenshot.png" border="1" alt="" /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;I&amp;#39;ve also included a bundle of the code and form for this sample as an attachment to this article. Have fun.&lt;br /&gt;&lt;/p&gt;
&lt;img src="http://customerfx.com/aggbug.aspx?PostID=40380" width="1" height="1"&gt;</content><author><name>Ryan Farley</name><uri>http://customerfx.com/members/Ryan-Farley.aspx</uri></author><category term="SalesLogix Web" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/SalesLogix+Web/default.aspx" /><category term="Customization" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Customization/default.aspx" /><category term="ASP.NET" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/ASP.NET/default.aspx" /><category term="Controls" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Controls/default.aspx" /></entry><entry><title>Relationship Property Names and Case</title><link rel="alternate" type="text/html" href="http://customerfx.com/pages/crmdeveloper/2009/03/27/relationship-property-names-and-case.aspx" /><id>http://customerfx.com/pages/crmdeveloper/2009/03/27/relationship-property-names-and-case.aspx</id><published>2009-03-27T18:38:00Z</published><updated>2009-03-27T18:38:00Z</updated><content type="html">&lt;p&gt;In today&amp;#39;s &lt;a href="http://customerfx.com/pages/events/pages/developer-training-building-solutions-for-saleslogix-web.aspx"&gt;SalesLogix Web Developer class&lt;/a&gt;, we discussed an issue that
someone in the class was having at runtime with a relationship that had a property that started with lower-case letters. Here are the details of that issue and
the fix:&lt;/p&gt;&lt;p&gt;&lt;font size="4"&gt;&lt;b&gt;Scenario&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;Create a entity named
&amp;quot;testProject&amp;quot; and then relate it to the Account entity. In the
relationship, the Account will have a collection named &amp;quot;testProjects&amp;quot;
(notice the property name starts lower case). You&amp;#39;ll then use that
relationship when you wire up your lookup on a form.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;font size="4"&gt;&lt;b&gt;Problem&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;Every
things builds fine, however at runtime you get an error saying &amp;quot;Could
not find field &amp;#39;_TestProjects&amp;#39; in class
Sage.SalesLogix.Entities.Account&amp;quot;. Notice that the error refers to the
property with an uppercase &amp;quot;T&amp;quot;.&lt;/p&gt;&lt;p&gt;&lt;font size="4"&gt;&lt;b&gt;Solution&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font size="4"&gt;&lt;b&gt;&lt;/b&gt;&lt;/font&gt;To fix this you just need to simply delete (or change) the relationship property to &lt;b&gt;NOT&lt;/b&gt; start lower-case. Always name your relationship properties Proper-case, starting with an upper case letter always. 

&lt;/p&gt;&lt;p&gt;&lt;br /&gt;I don&amp;#39;t know why this problem occurs. Seem that somewhere in the system an assumption is being made that the property name will be proper-cased (starting with an upper-case letter). However, I can tell you that you don&amp;#39;t see the problem if you use the first letter upper-cased for the properties created in the relationship. Weird.&lt;br /&gt;&lt;/p&gt;&lt;img src="http://customerfx.com/aggbug.aspx?PostID=40359" width="1" height="1"&gt;</content><author><name>Ryan Farley</name><uri>http://customerfx.com/members/Ryan-Farley.aspx</uri></author><category term="Issues and Bugs" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Issues+and+Bugs/default.aspx" /><category term="SalesLogix Web" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/SalesLogix+Web/default.aspx" /></entry><entry><title>Setting the Default Sort for a DataGrid in SalesLogix Web REVISITED</title><link rel="alternate" type="text/html" href="http://customerfx.com/pages/crmdeveloper/2009/03/26/setting-the-default-sort-for-a-datagrid-in-saleslogix-web-revisited.aspx" /><id>http://customerfx.com/pages/crmdeveloper/2009/03/26/setting-the-default-sort-for-a-datagrid-in-saleslogix-web-revisited.aspx</id><published>2009-03-26T21:28:00Z</published><updated>2009-03-26T21:28:00Z</updated><content type="html">&lt;p&gt;A while back I &lt;a href="http://customerfx.com/pages/crmdeveloper/2008/03/07/setting-the-default-sort-for-a-datagrid-in-saleslogix-web.aspx"&gt;wrote an article on setting the sort for a DataGrid in SalesLogix Web&lt;/a&gt; at runtime. That solution worked great in SalesLogix 7.2. However, things changed in SalesLogix 7.5 so I thought it was time for an update to that original post. Let&amp;#39;s see what changed and how to make it work again.&lt;/p&gt;
&lt;p style="font-weight:bold;"&gt;&lt;font size="3"&gt;&lt;a href="http://customerfx.com/pages/crmdeveloper/2008/03/07/setting-the-default-sort-for-a-datagrid-in-saleslogix-web.aspx"&gt;Take a look at the original article&lt;/a&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;In the original article, I mentioned that all this was possible because the SalesLogix DataGrid (Real class name SlxGridView) inherited from the ASP.NET GridView control. That hasn&amp;#39;t changed. However, here is what has changed:&lt;/p&gt;
&lt;p&gt;&lt;font size="4"&gt;&lt;span style="font-weight:bold;"&gt;Change #1: Where you LoadAction code is located&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-weight:bold;"&gt;&lt;/span&gt;The original &amp;quot;&lt;span style="font-weight:bold;font-style:italic;"&gt;C# Snippet Action Item&lt;/span&gt;&amp;quot; has been deprecated. This is what was used before. Now there is a &amp;quot;&lt;span style="font-weight:bold;font-style:italic;"&gt;Code Snippet Action Item&lt;/span&gt;&amp;quot; is what is used for code in LoadActions. The reason why this is significant is that the deprecated &amp;quot;C# Snippet Action Item&amp;quot; was placed inline in the SmartPart/ASCX file. So, you could rely on the fact that you could easily just reference controls on the form since the code also existed on the form. Now, with the new &amp;quot;Code Snippet Action Item&amp;quot;, the code is compiled into a separate assembly, much like the code in business rules. You are passed a reference to the form - which is not really a reference to the SmartPart class itself, but instead via an object that implements IForm and IEntityForm. &lt;/p&gt;
&lt;p&gt;&lt;font size="4"&gt;&lt;span style="font-weight:bold;"&gt;Change #2: In LoadAction code, you no longer get a direct reference to the controls&lt;/span&gt;&lt;/font&gt; &lt;br /&gt;&lt;/p&gt;
&lt;p&gt;This form object mentioned above exposes the controls on the form, however, not as the real control type, but as an adapter that wraps the control - only exposing certain things. For example, instead of exposing a reference to your SlxGridView (the datagrid), you get a reference to a faux-grid the implements IDataGridControl. This interface only provides access to a few handful of properties of the grid and the columns. The IDataGridControl implements IControl, which provides a few additional things, most notably, it provides a reference to the actual underlying control via an object property named NativeControl.&lt;/p&gt;
&lt;p&gt;&lt;font size="4"&gt;&lt;span style="font-weight:bold;"&gt;How do we make this work?&lt;/span&gt;&lt;/font&gt; &lt;br /&gt;&lt;/p&gt;
&lt;p&gt;Using the IControl interface, you can take the control adapter you are passed in the LoadAction code and get to the native control. That is a simple task and then you&amp;#39;ll be able to do anything you need with the native control reference. Here&amp;#39;s some sample code that get&amp;#39;s a reference to the native control and then does the sorting, just like before:&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;static&lt;/span&gt; partial &lt;span style="color:Blue;"&gt;class&lt;/span&gt; RelatedAccountsEventHandlers&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;static&lt;/span&gt; &lt;span style="color:Blue;"&gt;void&lt;/span&gt; Step(IAccountTickets form,  EventArgs args)&lt;br /&gt;    {&lt;br /&gt;        System.Web.UI.WebControls.GridView grid &lt;span style="color:Navy;"&gt;=&lt;/span&gt; (System.Web.UI.WebControls.GridView)form.grdAccountTickets.NativeControl;  &lt;br /&gt;        grid.Sort(&lt;span&gt;&amp;quot;ReceivedDate&amp;quot;&lt;/span&gt;, SortDirection.Descending);&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;Not so bad. The trick is knowing how to get to the underlying control from the adapter reference you are passed. One thing to note is that the code in the original article will still work in code in the now deprecated &amp;quot;C# Snippet Action Item&amp;quot;, so if you&amp;#39;ve used the code prior to 7.5, it will still work in the C# action. However, for new systems you need to use the new code above.&lt;br /&gt;&lt;/p&gt;
&lt;img src="http://customerfx.com/aggbug.aspx?PostID=40350" width="1" height="1"&gt;</content><author><name>Ryan Farley</name><uri>http://customerfx.com/members/Ryan-Farley.aspx</uri></author><category term="SalesLogix Web" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/SalesLogix+Web/default.aspx" /><category term="Application Architect" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Application+Architect/default.aspx" /><category term="SalesLogix 7.5" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/SalesLogix+7.5/default.aspx" /><category term="Controls" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Controls/default.aspx" /></entry><entry><title>Presentation of the Infusionsoft Outlook Integration at InfusionCon</title><link rel="alternate" type="text/html" href="http://customerfx.com/pages/crmdeveloper/2009/03/11/presentation-of-the-infusionsoft-outlook-integration-at-infusioncon.aspx" /><id>http://customerfx.com/pages/crmdeveloper/2009/03/11/presentation-of-the-infusionsoft-outlook-integration-at-infusioncon.aspx</id><published>2009-03-12T00:19:00Z</published><updated>2009-03-12T00:19:00Z</updated><content type="html">&lt;p&gt;I was out at &lt;a href="http://infusioncon.com/" target="_blank"&gt;InfusionCon&lt;/a&gt; today, the annual user conference for &lt;a href="http://infusionsoft.com/" target="_blank"&gt;Infusionsoft&lt;/a&gt;, for the public unveiling of the Infusionsoft Outlook Integration with &lt;a href="http://editweapon.com/" target="_blank"&gt;Patrick Sullivan&lt;/a&gt;. I&amp;#39;ve been really excited for the Outlook integration to get into the hands of the Infusionsoft masses because, frankly, it is so completely cool. Patrick and I met up early to make sure all was working and ran through the demo several times.&lt;/p&gt;&lt;p&gt;Flash forward to the actual demo. Things started well. There was even loud applause and cheering. That&amp;#39;s when things went downhill. Doh! Patrick&amp;#39;s Outlook started to try to connect to Exchange and sync up folders via the wireless at the resort (something that it wasn&amp;#39;t doing via Patrick&amp;#39;s Verizon wireless that we were rehearsing with). The connection to his Exchange server just wasn&amp;#39;t happening via the wireless connection from the resort so the result was that Outlook started freezing up while trying to sync the folders. Needless to say this made it, er, difficult for Patrick to continue demoing the integration. To be honest, it was disappointing to not get to show more than what we did, not because we were struggling through getting Outlook to behave, but because I think the Outlook integration rocks and I wanted for the Infusionsoft users to get to see all that it can do.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;However, it was surprising that despite the difficulties in demoing the integration that there was so much positive feedback about the integration. I guess people saw enough before the problems started to know that they liked what they saw. When it comes to knowing how software and UI &lt;span style="font-style:italic;"&gt;should work&lt;/span&gt;, Patrick is king. I think we&amp;#39;ve captured a completely unique yet intuitive experience in the integration. Best of all, this is just the beginning. If you&amp;#39;ve seen the integration or you&amp;#39;re using it already, be prepared to have your socks knocked off throughout this year. There is some mind-blowing stuff that will be coming in the integration. It&amp;#39;s great already, but we&amp;#39;re going to be &lt;a href="http://en.wikipedia.org/wiki/Up_to_eleven" target="_blank"&gt;taking it up to 11&lt;/a&gt; :-)&lt;/p&gt;&lt;p&gt;For those of you who have not yet seen it, you can see a short demo (the one that Patrick was &lt;span style="font-style:italic;"&gt;intending&lt;/span&gt; to do at InfusionCon) &lt;a href="http://www.screencast.com/users/editweapon/folders/Jing/media/6410d372-ff47-4483-8d58-991d378ac50a" target="_blank"&gt;here&lt;/a&gt; (be sure to click the &amp;quot;Full Size&amp;quot; button for full effect). &lt;span style="font-style:italic;"&gt;However, keep in mind that Patrick is using a new untested build (not the same publically available version) so there are a couple of very quick nasties that pop up in the video.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.screencast.com/users/editweapon/folders/Jing/media/6410d372-ff47-4483-8d58-991d378ac50a" target="_blank"&gt;&lt;font size="4"&gt;&lt;span style="font-weight:bold;"&gt;View Patrick&amp;#39;s Quick Video Demo of the Infusionsoft Outlook Integration&lt;/span&gt;&lt;/font&gt;&lt;/a&gt;&lt;br /&gt;&lt;font size="1"&gt;&lt;span style="font-style:italic;"&gt;(Be sure to click the &amp;quot;Full Size&amp;quot; button)&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;All in all, it was great to be at InfusionCon with the guys from Infusionsoft. What a completely exciting company.&lt;br /&gt;&lt;/p&gt;&lt;img src="http://customerfx.com/aggbug.aspx?PostID=40277" width="1" height="1"&gt;</content><author><name>Ryan Farley</name><uri>http://customerfx.com/members/Ryan-Farley.aspx</uri></author><category term="Infusionsoft" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Infusionsoft/default.aspx" /><category term="Outlook Integration" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Outlook+Integration/default.aspx" /></entry><entry><title>Determining if a User is a Member of a Team in SalesLogix Web</title><link rel="alternate" type="text/html" href="http://customerfx.com/pages/crmdeveloper/2009/02/04/determining-if-a-user-is-a-member-of-a-team-in-saleslogix-web.aspx" /><id>http://customerfx.com/pages/crmdeveloper/2009/02/04/determining-if-a-user-is-a-member-of-a-team-in-saleslogix-web.aspx</id><published>2009-02-04T21:13:00Z</published><updated>2009-02-04T21:13:00Z</updated><content type="html">
&lt;p&gt;Five years ago I wrote &lt;a href="http://customerfx.com/pages/crmdeveloper/2003/11/19/39084.aspx"&gt;a post about how to determine if a user is a member of a team&lt;/a&gt; in SalesLogix LAN scripts that is still referred to today. I&amp;#39;ve been asked on occasion how one would go about doing the same in the SalesLogix Web platform, so I thought it was time for a follow up post. In this post I will demonstrate how to use a &lt;a href="http://www.hibernate.org/hib_docs/nhibernate/1.2/reference/en/html/queryhql.html" target="_blank"&gt;HQL query&lt;/a&gt; to create a reusable function in the SalesLogix Web platform to determine whether a user is a member of a specified team.&lt;/p&gt;

&lt;p&gt;We will be creating this as a reusable method that we&amp;#39;ll pass a User object to as well as the team name we want to check. Let&amp;#39;s look at the code first and then we&amp;#39;ll look at how to use it and where you might create this reusable code:&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;span style="color:Blue;"&gt;private&lt;/span&gt; &lt;span style="color:Blue;"&gt;bool&lt;/span&gt; IsUserOnTeam(Sage.Entity.Interfaces.IUser user, &lt;span style="color:Blue;"&gt;string&lt;/span&gt; team)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:Blue;"&gt;using&lt;/span&gt; (NHibernate.ISession session &lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; Sage.Platform.Orm.SessionScopeWrapper())&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:Blue;"&gt;return&lt;/span&gt; 0 &amp;lt; Convert.ToInt32(session.CreateQuery(&lt;span&gt;&amp;quot;select count(*) from OwnerRights r where r.Owner.OwnerTypeChar = :type and r.Owner.OwnerDescription = :teamname and r.User.Id = :accessid&amp;quot;&lt;/span&gt;)&lt;br /&gt;                   .SetAnsiString(&lt;span&gt;&amp;quot;type&amp;quot;&lt;/span&gt;, Sage.SalesLogix.Security.StringEnum.GetStringValue(Sage.SalesLogix.Security.OwnerType.Team))&lt;br /&gt;                   .SetAnsiString(&lt;span&gt;&amp;quot;teamname&amp;quot;&lt;/span&gt;, team)&lt;br /&gt;                   .SetAnsiString(&lt;span&gt;&amp;quot;accessid&amp;quot;&lt;/span&gt;, user.Id.ToString())&lt;br /&gt;                   .UniqueResult());&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;The code above queries the SalesLogix entity model, looking at the OwnerRight entity specifically (this maps to the SECRIGHTS table in the database), and then limits that with conditions that the OwnerTypeChar property has the corresponding value for a team, the OwnerDescription has the correct team name, and to limit that to the OwnerRight entity instance where the UserId matches the Id of the User we pass in.&lt;/p&gt;

&lt;p&gt;The code to use it might look something like this:&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;Sage.SalesLogix.Security.SLXUserService usersvc &lt;span style="color:Navy;"&gt;=&lt;/span&gt; (Sage.SalesLogix.Security.SLXUserService)Sage.Platform.Application.ApplicationContext.Current.Services.Get&amp;lt;Sage.Platform.Security.IUserService&amp;gt;();&lt;br /&gt;Sage.Entity.Interfaces.IUser user &lt;span style="color:Navy;"&gt;=&lt;/span&gt; usersvc.GetUser();&lt;br /&gt; &lt;br /&gt;&lt;span style="color:Blue;"&gt;if&lt;/span&gt; (IsUserOnTeam(user, &lt;span&gt;&amp;quot;Midwest&amp;quot;&lt;/span&gt;))&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:Green;"&gt;// user is on the Midwest team&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;span style="color:Blue;"&gt;else&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:Green;"&gt;// user is NOT on the Midwest team&lt;br /&gt;&lt;/span&gt;}&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;Now, where might we implement something like this? Personally, I would create this as a separate assembly in Visual Studio and plug in where needed. However, you could also implement this in a business rule as well. If you implemented this code in a business rule, you&amp;#39;ll need to make sure the rule has the correct references. Otherwise it will produce an error when you build the web platform saying something about &amp;quot;are you sure you are not missing an assembly reference?&amp;quot;.&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;By default, the rule will have references to the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sage.Entity.Interfaces.dll&lt;/li&gt;

&lt;li&gt;Sage.Form.Interfaces.dll&lt;/li&gt;

&lt;li&gt;Sage.Platform.dll&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the code I outlined above, you&amp;#39;ll also need to have references for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&amp;nbsp;NHibernate.dll&lt;/li&gt;

&lt;li&gt;Sage.SalesLogix.Security.dll&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I won&amp;#39;t go into a whole lot of details now about how to add these references, I&amp;#39;ll have those steps outlined in a future post. However, while in the rule editor, open the Property pane (F4), click the drop-down at the top of the Properties pane and select &amp;quot;Sage.Platform.Orm.Entities.CodeSnippetHeader&amp;quot;. Then you&amp;#39;ll see properties for the CodeSnippetHeader for your code. You can bring up the AssemblyReferences and add the ones I mention above to that dialog. Things should complile fine now and you could shorten the code a bit too since you can add usings for these namespaces and drop the fully-qualified names of the objects. Just make sure you don&amp;#39;t try to add this rule to the User or other Security entities (See &lt;a href="http://customerfx.com/pages/crmdeveloper/2009/01/30/accessing-user-and-security-entity-properties-in-saleslogix-web.aspx"&gt;Accessing User and Security Entity Properties in SalesLogix Web&lt;/a&gt;)&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;One that thing I wanted to point out as well. The Owner object in Sage.SalesLogix.Security also has a similar function that will return a List&amp;lt;Owner&amp;gt; of all teams a specified user belongs to. That can come in handy as well. Here&amp;#39;s a sample that you could add to a LoadAction on a form to display a list of the teams the current user belongs to in a multi-line TextBox on the form called QFTextBox (Note: for this code, you do need a Sage.SalesLogix.Security.User object, not just a Sage.Entity.Interfaces.IUser reference since the method specifically takes a User, not IUser, parameter):&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;Sage.SalesLogix.Security.SLXUserService usersvc &lt;span style="color:Navy;"&gt;=&lt;/span&gt; (Sage.SalesLogix.Security.SLXUserService)Sage.Platform.Application.ApplicationContext.Current.Services.Get&amp;lt;Sage.Platform.Security.IUserService&amp;gt;();&lt;br /&gt;Sage.SalesLogix.Security.User user &lt;span style="color:Navy;"&gt;=&lt;/span&gt; usersvc.GetUser();&lt;br /&gt; &lt;br /&gt;System.Collections.Generic.IList&amp;lt;Sage.SalesLogix.Security.Owner&amp;gt; teamlist &lt;span style="color:Navy;"&gt;=&lt;/span&gt; Sage.SalesLogix.Security.Owner.GetTeamsByUser(user);&lt;br /&gt; &lt;br /&gt;&lt;span style="color:Blue;"&gt;string&lt;/span&gt; list &lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;"&gt;string&lt;/span&gt;.Empty;&lt;br /&gt;&lt;span style="color:Blue;"&gt;foreach&lt;/span&gt; (Sage.SalesLogix.Security.Owner team &lt;span style="color:Blue;"&gt;in&lt;/span&gt; teamlist)&lt;br /&gt;{&lt;br /&gt;    list += team.OwnerDescription &lt;span style="color:Navy;"&gt;+&lt;/span&gt; &lt;span&gt;&amp;quot;\r\n&amp;quot;&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;QFTextBox.Text &lt;span style="color:Navy;"&gt;=&lt;/span&gt; list;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;This code could also be used to check if a member is on a given team. However, the implementation of the method used in the Owner object will also return all the data in the List as well (and if I would have just used that I couldn&amp;#39;t have shown you the example using the HQL query). &lt;br /&gt;&lt;/p&gt;
&lt;img src="http://customerfx.com/aggbug.aspx?PostID=40156" width="1" height="1"&gt;</content><author><name>Ryan Farley</name><uri>http://customerfx.com/members/Ryan-Farley.aspx</uri></author><category term="Development" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Development/default.aspx" /><category term="SalesLogix Web" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/SalesLogix+Web/default.aspx" /><category term="Entity Model" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Entity+Model/default.aspx" /></entry><entry><title>Accessing User and Security Entity Properties in SalesLogix Web</title><link rel="alternate" type="text/html" href="http://customerfx.com/pages/crmdeveloper/2009/01/30/accessing-user-and-security-entity-properties-in-saleslogix-web.aspx" /><id>http://customerfx.com/pages/crmdeveloper/2009/01/30/accessing-user-and-security-entity-properties-in-saleslogix-web.aspx</id><published>2009-01-30T23:34:00Z</published><updated>2009-01-30T23:34:00Z</updated><content type="html">
&lt;p&gt;There are likely many cases in SalesLogix Web where you need to access properties on the User and Security related entities that are not included in the entity by default, meaning that there is no public property exposing the value. For example, the IsManager property on the User entity. A co-worker of mine ran into just this problem this week (See &lt;a href="http://customerfx.com/pages/integrationblog/2009/01/29/retrieving-the-manager-in-saleslogix-7-5-web.aspx"&gt;Retrieving the Manager in SalesLogix 7.5 Web&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="4"&gt;&lt;b&gt;The Problem&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;The root of the problem is that there are some often necessary properties on the User &amp;amp; Security related entities that are not included in the entity. See the image below:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://customerfx.com/blogs/crmdeveloper/User-SecurityProperties-IsManager.jpg" width="618" border="1" height="362" alt="" /&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;Notice in the image above that the &amp;quot;Include&amp;quot; checkbox is not checked for the IsManager property on the User entity. What the Include value means is whether to include a public accessor property for this when the entity is built. So, you might think that checking this checkbox and doing a build will make it available to you at runtime. You build &amp;amp; deploy and get no errors. However, when you attempt to access the site you get a runtime error that states the following:&lt;/p&gt;

&lt;p style="margin-left:40px;"&gt;&lt;span style="font-style:italic;"&gt;System.TypeLoadException: Method &amp;#39;get_ManagerId&amp;#39; in type &amp;#39;Sage.SalesLogix.Security.User&amp;#39; from assembly &amp;#39;Sage.SalesLogix.Security, Version=7.5.0.1484, Culture=neutral, PublicKeyToken=null&amp;#39; does not have an implementation&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;Here is why you are getting this error; the &amp;quot;Packages&amp;quot; in the entity model are more than just for the sake of organization. The &amp;quot;SalesLogix Security Support&amp;quot; package of entities does not just exist to separate these entities from the others. Each package is built to a separate assembly. They can have different templates for code generation. They can also have properties to indicate whether they are built into an assebmly at build time at all. This is the case with the User and Security entities in the SalesLogix Security Support package. If you open the package itself and &amp;quot;Build Settings&amp;quot; tab you will see something different about this package.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://customerfx.com/blogs/crmdeveloper/User-SecurityProperties-Package.jpg" width="458" border="1" height="157" alt="" /&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;You can see in the screenshot above that the SalesLogix Security Support package isn&amp;#39;t event built when you build the web platform. However, it&amp;#39;s interface is. When you check the Include checkbox on the IsManager property it is added to the interface. This is why you don&amp;#39;t get a compile error when you use it in a code snippet because you&amp;#39;re likely using the User entity via it&amp;#39;s interface. However, since the assembly is not built as well there is no implementation for the IsManager property that now exists in the IUser interface, hence the &amp;quot;does not have an implementation&amp;quot; error. Checking the box for &amp;quot;Generate Assembly&amp;quot; on the package won&amp;#39;t fix the problem. If you do, you&amp;#39;ll get compile errors. These User and Security entities are available in the Application Architect so you can create relationships to them from other entities, however their implementation is quite different and the standard code generation templates will not account for all the extra things they do. So, what is the solution?&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p style="font-weight:bold;"&gt;&lt;font size="4"&gt;The Solution&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;Knowing why you&amp;#39;re getting the errors and what the problem is does not exactly help in getting to these not-included values that you need from these entities. However, there is hope. When you access any entity in SalesLogix code, you&amp;#39;re likely accessing the entity via it&amp;#39;s interface (as you should). However, I mentioned above that there is a lot more to the implementation of the User and Security entities. That is where you&amp;#39;ll find what you need.&lt;/p&gt;

&lt;p&gt;Normally, you would access a User, such as the current user, like this:&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;Sage.SalesLogix.Security.SLXUserService usersvc &lt;span style="color:Navy;"&gt;=&lt;/span&gt; (Sage.SalesLogix.Security.SLXUserService)Sage.Platform.Application.ApplicationContext.Current.Services.Get&amp;lt;Sage.Platform.Security.IUserService&amp;gt;();&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Sage.Entity.Interfaces.IUser&lt;/span&gt; user &lt;span style="color:Navy;"&gt;=&lt;/span&gt; usersvc.GetUser();&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;Note that you are accessing the User via the IUser interface. Now, the IUser interface is just a standard entity interface. Since the interface is being built when you do a &amp;quot;Build Web Platform&amp;quot; (note, the checkbox to build it&amp;#39;s interface is checked for the package) it is a true representation of what you see in the Application Architect. However, there is quite a bit more to it&amp;#39;s implementation found in the User class. Fire up Reflector and take a look at some of the things available in Sage.SalesLogix.Security.User:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://customerfx.com/blogs/crmdeveloper/User-SecurityProperties-Reflector.jpg" border="0" alt="" /&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;Notice all the extra goodies there to use? For example, the Manager property, that returns a Manager object. The Manager class simply inherits from User, meaning that it has all the properties and methods that a User object has as well as a few more. To use this property, as well as the others in the User class, you just need to use the reference via the User class instead of via the IUser interface. Something like this:&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;span style="color:Green;"&gt;// get the current user as a User (not IUser)&lt;br /&gt;&lt;/span&gt;Sage.SalesLogix.Security.SLXUserService usersvc &lt;span style="color:Navy;"&gt;=&lt;/span&gt; (Sage.SalesLogix.Security.SLXUserService)Sage.Platform.Application.ApplicationContext.Current.Services.Get&amp;lt;Sage.Platform.Security.IUserService&amp;gt;();&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Sage.SalesLogix.Security.User&lt;/span&gt; user &lt;span style="color:Navy;"&gt;=&lt;/span&gt; usersvc.GetUser();&lt;br /&gt;&lt;br /&gt;&lt;span style="color:Green;"&gt;// now get the user&amp;#39;s Manager&lt;br /&gt;&lt;/span&gt;Sage.SalesLogix.Security.Manager manager &lt;span style="color:Navy;"&gt;=&lt;/span&gt; user.Manager;&lt;br /&gt;&lt;span style="color:Blue;"&gt;string&lt;/span&gt; manageremail &lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;span&gt;&amp;quot;Manager e-mail: &amp;quot;&lt;/span&gt; &lt;span style="color:Navy;"&gt;+&lt;/span&gt; manager.UserInfo.Email;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;Note that the code is basically the same as when you accessed the User via the IUser interface. You just use the actual implementation class instead and you can get to what you need.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p style="font-weight:bold;"&gt;&lt;font size="4"&gt;A Solution for All Cases?&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;This is not a solution for every case. There will without question be some properties that you just can&amp;#39;t get to. The &amp;quot;last resort&amp;quot; solution to access these inaccessible properties is to go to the database. You can easily get a connection to the underlying database and use that to query for the value you&amp;#39;re after. Here&amp;#39;s an example:&lt;/p&gt;

&lt;table style="table-layout:fixed;width:600px;" cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;span style="color:Green;"&gt;// get the manager&amp;#39;s e-mail address using a connection to the database&lt;br /&gt;//&lt;br /&gt;// Note: this is just for example purposes, instead of doing this&lt;br /&gt;// use the user.Manager property available on Sage.SalesLogix.Security.User&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:Blue;"&gt;string&lt;/span&gt; manageremail &lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;"&gt;string&lt;/span&gt;.Empty;&lt;br /&gt;&lt;span style="color:Green;"&gt;// get the DataService to get a connection string to the database&lt;br /&gt;&lt;/span&gt;Sage.Platform.Data.IDataService datasvc &lt;span style="color:Navy;"&gt;=&lt;/span&gt; Sage.Platform.Application.ApplicationContext.Current.Services.Get&amp;lt;Sage.Platform.Data.IDataService&amp;gt;();&lt;br /&gt;&lt;span style="color:Blue;"&gt;using&lt;/span&gt; (System.Data.OleDb.OleDbConnection conn &lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; System.Data.OleDb.OleDbConnection(datasvc.GetConnectionString()))&lt;br /&gt;{&lt;br /&gt;    conn.Open();&lt;br /&gt;    &lt;span style="color:Blue;"&gt;using&lt;/span&gt; (System.Data.OleDb.OleDbCommand cmd &lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; System.Data.OleDb.OleDbCommand(&lt;span&gt;&amp;quot;select u1.email from userinfo u1 inner join usersecurity u2 on u1.userid = u2.managerid where u2.userid = &amp;#39;&amp;quot;&lt;/span&gt; &lt;span style="color:Navy;"&gt;+&lt;/span&gt; user.Id.ToString() &lt;span style="color:Navy;"&gt;+&lt;/span&gt; &lt;span&gt;&amp;quot;&amp;#39;&amp;quot;&lt;/span&gt;, conn))&lt;br /&gt;    {&lt;br /&gt;        object o &lt;span style="color:Navy;"&gt;=&lt;/span&gt; cmd.ExecuteScalar();&lt;br /&gt;        &lt;span style="color:Blue;"&gt;if&lt;/span&gt; (o !&lt;span style="color:Navy;"&gt;=&lt;/span&gt; &lt;span style="color:Blue;"&gt;null&lt;/span&gt;) manageremail &lt;span style="color:Navy;"&gt;=&lt;/span&gt; o.ToString();&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;This is not an ideal solution, and isn&amp;#39;t meant to be.In my opinion, accessing the database directly should absolutely be a last resort and avoided if possible. Why, the entity model is rich and complete in most cases. The majority of times I&amp;#39;ve seen someone go direct to the database it is more than likely because of a lack of knowledge of how to do something in the entity model, not because the entity model could not provide what was needed. Business rules that might be in place in the entity model will not apply to things you do in the database (unless they are implemented in Process Orchestration). &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;Ideally these properties in the implementation that are hidden by their absence in the interface would just be included in the interface. However, knowing that some of these things are there, and how to get to them, will definitely save you some headaches.&lt;br /&gt;&lt;/p&gt;
&lt;img src="http://customerfx.com/aggbug.aspx?PostID=40150" width="1" height="1"&gt;</content><author><name>Ryan Farley</name><uri>http://customerfx.com/members/Ryan-Farley.aspx</uri></author><category term="Development" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Development/default.aspx" /><category term="SalesLogix Web" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/SalesLogix+Web/default.aspx" /><category term="C#" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/C_2300_/default.aspx" /><category term="Entity Model" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Entity+Model/default.aspx" /><category term="Application Architect" scheme="http://customerfx.com/pages/crmdeveloper/archive/tags/Application+Architect/default.aspx" /></entry></feed>