20 Nisan 2011 Çarşamba

MS CRM 4.0’da Performansı artırmak için AsyncOperationBase ve WorkflowLogBase Tablolarının Silinmesi

Merhaba arkadaşlar bugün sizlere Microsoft Dynamics CRM 4.0'da performansı artırmak için düzenli yapılması gereken bazı tekniklerden bahsedeceğim. Microsoft Dynamics CRM 4.0'da çok sayıda iş akışı kullanırız. AsyncOperationBase ve WorkflowLogBase tablolarının boyutu çok fazla artar ve performans sorunlarıyla karşılaşılır. Bu sorun, iş akışı kuralları uygulanırken MSCRM veritabanındaki AsyncOperationBase ve WorkflowLogBase tablolarında bir iş akışı örneği ve bir iş akışı kaydı oluşturulması nedeniyle ortaya çıkar. Ancak iş akışı örneği tamamlandığında, iş akışı kaydı veritabanında kalır. Bu nedenle, AsyncOperationBase ve WorkflowLogBase tabloları büyümeye devam eder. Zaman içinde performans düşer.

Bu işlemi  aşağıdaki sorguyu çalıştırak silebilirsiniz. Detaylı bilgiyi bu link’den alabilirisiniz. (http://support.microsoft.com/kb/968520/tr)


IF EXISTS (SELECT name from sys.indexes
WHERE name = N'CRM_AsyncOperation_CleanupCompleted')
DROP Index AsyncOperationBase.CRM_AsyncOperation_CleanupCompleted
GO
CREATE NONCLUSTERED INDEX CRM_AsyncOperation_CleanupCompleted
ON [dbo].[AsyncOperationBase] ([StatusCode],[StateCode],[OperationType])
GO
declare @DeleteRowCount int
Select @DeleteRowCount = 2000
declare @DeletedAsyncRowsTable table (AsyncOperationId uniqueidentifier not null primary key)
declare @continue int, @rowCount int
select @continue = 1
while (@continue = 1)
begin
begin tran
insert into @DeletedAsyncRowsTable(AsyncOperationId)
Select top (@DeleteRowCount) AsyncOperationId
from AsyncOperationBase
where OperationType in (1, 9, 12, 25, 27, 10) AND StateCode = 3 AND StatusCode in (30, 32)     
Select @rowCount = 0
Select @rowCount = count(*) from @DeletedAsyncRowsTable
select @continue = case when @rowCount <= 0 then 0 else 1 end     
if (@continue = 1)
begin
delete WorkflowLogBase from WorkflowLogBase W, @DeletedAsyncRowsTable d
where W.AsyncOperationId = d.AsyncOperationId
delete BulkDeleteFailureBase From BulkDeleteFailureBase B, @DeletedAsyncRowsTable d
where B.AsyncOperationId = d.AsyncOperationId
delete AsyncOperationBase From AsyncOperationBase A, @DeletedAsyncRowsTable d
where A.AsyncOperationId = d.AsyncOperationId            
delete @DeletedAsyncRowsTable
end
commit
end
--Drop the Index on AsyncOperationBase
DROP INDEX AsyncOperationBase.CRM_AsyncOperation_CleanupCompleted


Veya custom bir uygulama yazarak istediğiniz bir zamana ayarlayıp çalıştırabilirsiniz. Aşağıdaki gibi bir Console uygulaması yazarak toplu silme özelliğini kullanabilirsiniz.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BulkDeleteMessageSample.CrmSdk;
using CrmSdk;

namespace CrmSdk
{
    class Program
    {
        static void Main(string[] args)
        {
            // Set up the CRM Service.
            CrmAuthenticationToken token = new CrmAuthenticationToken();
            token.AuthenticationType = 0;
            token.OrganizationName = "OrganizasyonAdi";

            CrmService service = new CrmService();
            service.CrmAuthenticationTokenValue = token;
            service.Credentials = System.Net.CredentialCache.DefaultCredentials;

            runBulkDelete(service);
        }

        static void runBulkDelete(CrmService service)
        {
            // Create a query expression using the QueryExpressionHelper
            QueryExpressionHelper expression = new QueryExpressionHelper("asyncoperation");
            expression.Columns.AddColumn("asyncoperationid");
            expression.Criteria.Conditions.AddCondition("statecode", ConditionOperator.Equal, (int)AsyncOperationState.Completed);
            expression.Criteria.Conditions.AddCondition("completedon", ConditionOperator.OlderThanXMonths, 1);
            expression.Criteria.Conditions.AddCondition("operationtype", ConditionOperator.NotEqual, (int)AsyncOperationType.Import);

            Guid[] emptyRecipients = new Guid[0];
            BulkDeleteRequest request = new BulkDeleteRequest();
            request.JobName = "Bulk delete completed asyncoperations to free up space";
            request.QuerySet = new QueryBase[] { expression.Query };
            request.ToRecipients = emptyRecipients;
            request.CCRecipients = emptyRecipients;
            request.SendEmailNotification = false;
            request.RecurrencePattern = string.Empty;
            request.StartDateTime = CrmDateTime.Now;

            BulkDeleteResponse response = (BulkDeleteResponse)service.Execute(request);

            Console.WriteLine("Bulk delete job with id: {0} has been created", response.JobId);
            Console.ReadLine();
        }
    }
}


Gelecek yazımda görüşmek dileğiyle..

7 Ocak 2011 Cuma

Paylaşım Üzerinde Klasör Oluşturma(Ms Crm 4.0 için belge yönetimi)


Merhaba arkadaşlar bugün sizlere javascript kodlarını kullanarak yazdığım işinizi kolaylaştıracak güzel bir kod parçasından bahsedeceğim. Bu kodu yayımlamamdaki  amacım aynı network içinde veya paylaşıma açılmış bir klasörde her müşteri için unique bir klasör oluşturmak.  Oluşturduğunuz bu klasörde kayıtla ilgili istediğiniz her türlü dosyayı atıp saklayabileceğiniz bir yapı meydana getirmek. Kısaca dökümanlarınızı paylaşım üzerinden  yönetebileceğiniz basit bir yapı olacak. Öncellikle ayarlardan ‘’ varlıkları özelleştire ‘’ girerek ilgili kişi varlığını seçelim ve ‘’ özelliklere ‘’ girerek yeni bir nvarchar alan oluşturalım. Bu alanı form üzerinde uygun bir yere koyduktan sonra formun onload’una aşağıdaki kodu yazalım.


/////////////////////////////Dosya Paylaşımı///////////////////////////////////////
var oShell = new ActiveXObject("Scripting.FileSystemObject");
var Path="\\\\server\\CrmMusterilerininDosyalari\\"+crmForm.ObjectId; //Network’de paylaşıma açtığınız klasörün içine ilgili kayıdın Id’sini alarak yeni klasör oluşturuyor.
  if (! oShell.FolderExists(Path) )
{
  oShell.CreateFolder(Path)
//alert("Dosya açıldı");
}    
crmForm.all.new_paylasim.DataValue=Path;
var urlField =crmForm.all.new_paylasim;

//Set the text color to blue
urlField.style.color = 0x0000ff;

//Display the text underlined
urlField.style.textDecorationUnderline = true;

//Use the hand cursor
urlField.style.cursor = "hand";

//Add the ondblclick (or onclick) event handler to open target site in a new window
urlField.ondblclick = function() {
//Get the url from value in the field
var url = urlField.DataValue; // Or get it from somewhere else

//If the url is not empty
if (url != null && url.length > 0) {
window.open(url);
}
}
///////////////////////////////////////////////////////////////////////////////////////

Yukarıdaki  kodu formun onload’una yazıp yayımladıktan sonra form her açıldığında klösörün olup olmadığı kontrolünü yapacak eğer kayda ait klasör yoksa yeni bir klasör oluşturacak ve açmış olduğumuz  alan üzerine klasörü link şeklinde gösterecek.
Bir sonraki yazımda görüşmek dileğiyle,hepinize başarılar dilerim...

4 Ocak 2011 Salı

E-mail Uygulaması(Birthday Reminder)


Merhaba arkadaşlar bugün sizlere MS CRM  web servisini  ve   C# kodlarını kullanarak nasıl e-mail göndereceğinizi anlatacağım. Uygulama tamamlandığında doğum günü olan ilgili kişileri kontrol edebilecek , e-mail aktivitesi oluşturarak e*mail gönderebileceksiniz.  email’leri crm üzerinden göndermek için Email Router bu link’den indirebilirsiniz.  Email Router  kurup Exchange veya POP3 ayarlarını yapdıktan sonra kodlarımızı yazmaya başlayabiliriz. Öncellikle  visual studio uygulamamızı açıp yeni bir Console projesi açalım. Daha sonra  web servis nesnelerine ulaşmak için add web reference diyerek projenize http:// server adı>/mscrmservices/2007/CrmServiceWsdl.aspx  dahil edelim.



 Daha sonra kullanacağımız metotların geldiğini göreceksiniz.



using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using EmailApplication.CrmWs;
using EmailApplication.Properties;

namespace EmailApplication
{
    class Program
    {

        static void Main(string[] args)
        {
            //İlgili kişiler varlığından email adresi boş olmayan ve doğum günü bugün olan kişlerin listesini alalım.
            string Query = @"
                                        DECLARE @UTCDiff INT
                                        SET @UTCDiff = DATEDIFF(HOUR, GetUTCDate(), GETDATE())
                                        SELECT
                                               f.fullname AS fullname,
                                               f.contactid AS contactid,
                                            f.fullname AS contactname,
                                               f.birthdate AS birthdate,
                                               f.emailaddress1 AS email                                                                                                                                     
                                        FROM
                                               FilteredContact AS f WITH (NOLOCK)                                                                         
                                        WHERE
                                               f.birthdate IS NOT NULL
                                               AND (DAY(DATEADD(hh, @UTCDiff, f.birthdate)) = DAY(GETDATE()))
                                               AND (MONTH(DATEADD(hh, @UTCDiff, f.birthdate)) = MONTH(GETDATE()))    
                                               AND f.emailaddress1 IS NOT NULL
                                        ORDER BY f.fullname";
            try
            {
                DataTable dt = new DataTable();
                SqlConnection con = GetCrmSqlConnection();

                if (con != null)
                {
                    SqlDataAdapter adap = new SqlDataAdapter(Query, con);
                    adap.Fill(dt);
                    if (dt.Rows.Count != 0)
                    {
                        SendEmail(dt);
                    }
                }
            }
            catch (Exception ex)
            {
                //throw new Exception(ex.Message);
                throw ex;
            }

        }
        private static void SendEmail(DataTable dt)
        {
            try
            {
                email mail = new email(); // Email sınıfını oluşturalım.
                activityparty from = new activityparty();
                activityparty toSingle = null;
                from.partyid = new Lookup();
                from.partyid.type = EntityName.systemuser.ToString();
                from.partyid.Value = new Guid(Settings.Default.From.ToString()); // Gönderen Id'si
                mail.from = new activityparty[] { from };
                if (dt != null)
                {
                    CrmService servis = ConnectService(); //crm servisini çağıralım.
                    activityparty[] to;

                    for (int i = 0; i < dt.Rows.Count; i++)
                    {
                        to = new activityparty[dt.Rows.Count];
                        toSingle = new activityparty();
                        toSingle.partyid = new Lookup();
                        toSingle.partyid.type = EntityName.contact.ToString();
                        toSingle.partyid.Value = new Guid(Convert.ToString(dt.Rows[i]["contactid"]));
                        to[i] = toSingle;
                        mail.to = to;
                        mail.subject = "Doğum Gününüz Kutlu Olsun.";                   
                        CrmBoolean direction = new CrmBoolean();
                        direction.Value = true;
                        mail.directioncode = direction;      
                        Guid mailId = servis.Create(mail);
                        GetTrackingTokenEmailRequest getRequest = new GetTrackingTokenEmailRequest();
                        getRequest.Subject = mail.subject;
                        GetTrackingTokenEmailResponse getResponse = (GetTrackingTokenEmailResponse)servis.Execute(getRequest);
                        SendEmailRequest request = new SendEmailRequest();
                        request.EmailId = mailId;
                        request.IssueSend = true;
                        request.TrackingToken = getResponse.TrackingToken;
                        SendEmailResponse response = (SendEmailResponse)servis.Execute(request);
                        //}
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

        private static CrmService ConnectService()
        {          
            CrmService servis = null;
            try
            {
                servis = new CrmService();
                CrmWs.CrmAuthenticationToken token = new CrmWs.CrmAuthenticationToken();
                token.AuthenticationType = 0;
                token.OrganizationName = "crm";
                servis.CrmAuthenticationTokenValue = token;
                servis.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;

            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            return servis;
        }

        private static SqlConnection GetCrmSqlConnection()
        {
            string connStr = null;
            SqlConnection conn = null;
            try
            {
                connStr = String.Format("Data Source=.;Initial Catalog=ORG_MSCRM;Integrated Security=True");
                conn = new SqlConnection(connStr);
            }
            catch (SqlException ex)
            {
                throw new Exception(ex.Message);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            return conn;
        }

    }

}

Bir sonraki yazımda görüşmek üzere, Herkese başarılar dilerim.


7 Aralık 2010 Salı

Microsoft Dynamics CRM 4.0 Performance Toolkit

Merhaba arkadaşlar size güzel bir tool'dan bahsedeceğim codeplex'den indirebileceğiniz bu tool ms crm 4.0 performansını ölçmek için kullanabileceğiniz bir tool'dur. Bu tool'u canlı ortam yerine test ortamınızda test etmenizi öneririm. Aşağıdaki özellikleri test edebilirsiniz.
1. Multi Organization Performance Testing Support
2. Multi Server Deployment Performance Testing Support
3. Outlook Synchronization and Offline Performance Testing Support
4. Data Management Performance Testing Support
5. Workflow Performance Analysis Support
6. Email Matching Performance Testing Support
7. Ease of deployment of the Toolkit through an MSI package with enhanced configuration of the toolkit.

Bu link'den tool'u indirebilirsiniz.

8 Kasım 2010 Pazartesi

Kullanıcının Id'sini Alma Script'i(Get Current UserId)

Merhaba arkadaşlar crm'i kullanan kullanıcının(WhoAmI) id'sini aşağıdaki script'i form'un onload'una yazarak bulabilirsiniz.

alert(GetCurrentUserId());

function createCookie(name,value,days) {
if (days) {
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
var expires = "; expires="+date.toGMTString();
}
else var expires = "";
document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) { var c = ca[i]; while (c.charAt(0)==' ') c = c.substring(1,c.length); if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length); } return null; } function GetCurrentUserId() { try { var UserId = readCookie('UserId') ; if ( UserId == null ) { var soapBody = ""+
""+
""+
"
";

var soapXml = "";

soapXml += GenerateAuthenticationHeader();
soapXml += soapBody;
soapXml += "
";

var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
xmlhttp.open("POST", "/mscrmservices/2007/crmservice.asmx", false);

xmlhttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xmlhttp.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/crm/2007/WebServices/Execute");

xmlhttp.send(soapXml);
xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async=false;
xmlDoc.loadXML(xmlhttp.responseXML.xml);

createCookie('UserId',xmlDoc.getElementsByTagName("UserId")[0].childNodes[0].nodeValue,1);
//var buid = xmlDoc.getElementsByTagName("BusinessUnitId")[0].childNodes[0].nodeValue;
//var orgid = xmlDoc.getElementsByTagName("OrganizationId")[0].childNodes[0].nodeValue;

return xmlDoc.getElementsByTagName("UserId")[0].childNodes[0].nodeValue;

}
else
return UserId;
}
catch(err)
{
}
}

Microsoft Dynamics CRM 2011 Walkthrough Part 2

14 Ekim 2010 Perşembe

Microsoft Dynamics CRM 2011 Walkthrough Part 1

Merhaba arkadaşlar aşağıdaki slayt da CRM2011'le gelen bazı özellikleri görebilirsiniz.