Wednesday 5 November 2014

How to fetch more than 5000 entities from CRM

Let's start with simple example to get all entities from CRM

public EntityCollection GetEntities(string entityName)
{
    var config = ServerConnection.GetServerConfiguration();
    var proxy = ServerConnection.GetOrganizationProxy(config);

    string request = string.Format(@"<fetch mapping ='logical'>
               <entity name = '{0}'></entity></fetch>", entityName);
    FetchExpression expression = new FetchExpression(request);
    var mult = proxy.RetrieveMultiple(expression);

    return mult;           
}
This will work, but will return maximum of 5000 elements in mult.Entities.
Let's add paging now and put that in loop until mult.MoreRecords is false.

string request = string.Format(@"<fetch
                count='5000' page='{1}' mapping ='logical'>
                <entity name = '{0}'></entity></fetch>"
, entityName, page++);
But now Paging cookie is required when trying to retrieve a set of records on any high pages.
Paging cookie is returned in EntityCollection.PagingCookie property. Also, XML tags must be encoded, because this is xml-in-xml.

pagingCookie = string.Format("paging-cookie='{0}'",
    System.Web.
HttpUtility.HtmlEncode(mult.PagingCookie));

Now, complete method looks like this:

public IList<Entity> GetEntitiesNoLimit(string entityName)
{
    var config = ServerConnection.GetServerConfiguration();
    IOrganizationService proxy = ServerConnection.GetOrganizationProxy(config);

    var entities = new List<Entity>();
    int page = 1;
    string pagingCookie = string.Empty;
    while (true)
    {
        string request = string.Format(@"<fetch {2} count='5000' page='{1}'
                         mapping ='logical'><entity name = '{0}'></entity></fetch>",
                         entityName, page++, pagingCookie);
        FetchExpression expression = new FetchExpression(request);
        var mult = proxy.RetrieveMultiple(expression);
        entities.AddRange(mult.Entities);
        if (mult.MoreRecords)
        {
            pagingCookie = string.Format("paging-cookie='{0}'",
                        System.Web.HttpUtility.HtmlEncode(mult.PagingCookie));
        }
        else
        {
            break;
        }
    }

    return entities;
}

Tuesday 4 November 2014

Tuesday 28 October 2014

SSIS - find element in table, use its key and insert to another table

I have database with following 3 tables:
·         Customers.CustomerId is integer and PK
·         Addresses.AddressId is integer and PK
·         CustomerAddresses.Customer_CustomerId is integer and FK to Customers
·         CustomerAddresses.Address_AddressId is integer and FK to Addresses
·         Customers.EntityId is GUID
·         Addresses.EntityId is GUID

I use SQL Server Integration Services.
I have also XML file with pairs of addressEntityID and customerEntityId. These are are EntityIDs (GUID), that need to be mapped to IDs (integer) and inserted into CustomerAddresses.

How to map this relationship and import to CustomerAddresses?
1.  In Data Flow drop XML source
2.  Add Derived column, map values from XML (from string to GUID)

3.  Add Lookup, connect to Addresses table, create JOIN from derived AddressGuid to EntityId. AddressId is output.
4.  Add another Lookup and do the same for Customers table
On "Specify how to handle rows with no matching entries" choose "Redirect rows to error output".
5.  Add DB destination, map values from Lookup to AddressId and CustomerId

Complete Data Flow

Monday 27 October 2014

Drop all foreign keys

DECLARE @SQL varchar(4000)=''
SELECT @SQL = @SQL + 'ALTER TABLE ' + FK.TABLE_NAME + ' DROP CONSTRAINT [' + RTRIM(C.CONSTRAINT_NAME) +'];' + CHAR(13)
  FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS C
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS FK
    ON C.CONSTRAINT_NAME = FK.CONSTRAINT_NAME
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS PK
    ON C.UNIQUE_CONSTRAINT_NAME = PK.CONSTRAINT_NAME
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE CU
    ON C.CONSTRAINT_NAME = CU.CONSTRAINT_NAME
INNER JOIN (
            SELECT i1.TABLE_NAME, i2.COLUMN_NAME
              FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS i1
             INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE i2
                ON i1.CONSTRAINT_NAME = i2.CONSTRAINT_NAME
            WHERE i1.CONSTRAINT_TYPE = 'PRIMARY KEY'
           ) PT
    ON PT.TABLE_NAME = PK.TABLE_NAME

EXEC (@SQL)

PRINT @SQL

Friday 24 October 2014

Search within range with LINQ and DbGeography

    var myLocation = DbGeography.FromText(string.Format("POINT({0} {1})", lon, lat)); 
    var result = (from u in _db.Restaurants
           orderby u.Location.Distance(myLocation)
           where u.Location.Distance(myLocation) < distance
           select u).Take(limit).ToList();
distance is a double and its value is in meters.

Thursday 23 October 2014

Mobile site - device channel configuration

1.       Go to Site collection features and activate SharePoint Server Publishing Infrastructure


2.       Go to Device Channels

3.       Create new device channel, give it alias "mobile". Under Device Inclusion Rules enter user agent substrings for devices, that should use mobile view. Check as active.

Wednesday 22 October 2014

Przechowywanie datasource pomiędzy PostBack

        private string _countriesList = "countries";
        private List<CountryInfo> _countries;
        private List<CountryInfo> Countries
        {
            get
            {
                if (ViewState[_countriesList] == null)
                    return new List<CountryInfo>();
                return (List<CountryInfo>)ViewState[_countriesList];
            }
            set
            {
                ViewState[_countriesList] = value;
                _countries = value;
            }

        }

Thursday 27 February 2014

Elements appear when mouse hovers above them - CSS and jQuery

I'm going to share that with you, because it took me surprisingly long time to figure out.

I wanted to have an element, that shows up only, when mouse moves over the element. Just like this:
My first idea was to use "hide()" and "show()" methods on elements themselves. Unfortunately, when elements were hidden, they had no size (or actually size was 0), so you could not hover over them to show them.

Second idea, was to use CSS, and change visibility in ":hover" style. That worked partially - the <div> element had <i> child. Only child would be visible (after all, it's cascading style sheets, it does not go up).

My final idea, was to contain my elements in larger <div> element. The DIV has fixed size and position, and display: block. Child elements are initially hidden. Then I bind "hover()" event to the parent div, that finds children, and displays them. And then hides, when mouse leaves.

So, this is the markup:
<div class="show">
    <div class="mouseover"><i class="fa fa-something"></i></div>
    <div class="mouseover"><i class="fa fa-something-else"></i> </div>
</div>

And this is the script:
$(function(){
    $('.show').hover(
    function() {
        $(this).find('.mouseover').fadeIn();
    },
    function() {
        $(this).find('.mouseover').fadeOut();
    });
});

Monday 24 February 2014

Web.config changing when publishing application - how to avoid it?

I have MVC website, that I deployed to Azure. The application uses EF Code First. 

After deployment, these lines were added to web.config:

  <connectionStrings>
    <add name="LoremIpsum.LoremContext" 
         connectionString="LoremIpsum.LoremContext_ConnectionString" 
         providerName="System.Data.SqlClient" />
  </connectionStrings>

This caused this error:

Format of the initialization string does not conform to specification starting at index 0.

I solved this by going to my Publish Profile (the .pubxml file) and deleted following lines:

  <ItemGroup>
    <MSDeployParameterValue Include="$(DeployParameterPrefix)LoremIpsum.LoremContext-Web.config Connection String">
      <ParameterValue>... my actual connection string ...</ParameterValue>
    </MSDeployParameterValue>
  </ItemGroup>
  <ItemGroup>
    <_ConnectionStringsToInsert Include="LoremIpsum.LoremContext" />
  </ItemGroup>