mardi 1 juillet 2014

Filter DataGridView out of the DbContext

Imagine you load data into a DataGridView.DataSource from a database.
Then you want to allow end user to filter the results, but without hitting database again.
So you use a TextBox to prompt a filter an, OnTextChanged
private void tbFilter_TextChanged(object sender, EventArgs e) {
    CurrencyManager cm = (CurrencyManager)BindingContext[dgvList.DataSource];
    cm.SuspendBinding();
    foreach (DataGridViewRow r in dgvList.Rows) {
        r.Visible = String.IsNullOrEmpty(tbFilter.Text) || r.Cells[1].Value.ToString().Contains(tbFilter.Text);
    }
    cm.ResumeBinding();
}
Here the difficulty is the use of a CurrencyManager.

samedi 10 mai 2014

using UserManager/IdentityFramework with an Int32 as TKey for IUser

This article is about how to use Int32 as a key for users in asp.net identity.

First the model. As I seed it, you can also see how to instanciate the UserManage.

For this thank you to SymbolSource and to Microsoft of course!

namespace cclw4c.Models
{
    // You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more.
    public class ApplicationUser : IdentityUser <Int32, CustomUserLogin, CustomUserRole, CustomUserClaim&gt: {
    }

    public class CustomRole : IdentityRole<Int32, CustomUserRole> {
        public CustomRole() { }
        public CustomRole(String name) { Name = name; }
    }

    public class CustomUserRole : IdentityUserRole<Int32> { }
    public class CustomUserClaim : IdentityUserClaim<Int32> { }
    public class CustomUserLogin : IdentityUserLogin<Int32> { }

    public class ApplicationUserDbContext : IdentityDbContext<ApplicationUser, CustomRole, Int32, CustomUserLogin, CustomUserRole, CustomUserClaim>
    {
        public ApplicationUserDbContext()
            : base("ApplicationUser")
        {
            Database.SetInitializer<ApplicationUserDbContext>(new CreateDatabaseIfNotExistsWithSeedData());
        }

        
    }

    public class CreateDatabaseIfNotExistsWithSeedData : CreateDatabaseIfNotExists<ApplicationUserDbContext> {
        protected override void Seed(ApplicationUserDbContext context) {
            base.Seed(context);

            var user = new ApplicationUser() { UserName = "root" };
            UserManager<ApplicationUser, Int32> am = 
                new UserManager<ApplicationUser, Int32>(new UserStore<ApplicationUser, CustomRole, Int32, CustomUserLogin, CustomUserRole, CustomUserClaim>(context));
            IdentityResult ir = am.Create(user, "******");
            if (ir.Succeeded) {
                RoleManager<CustomRole, Int32> rm = new RoleManager<CustomRole, Int32>(new RoleStore<CustomRole, Int32, CustomUserRole>(context));
                rm.Create(new CustomRole("Root"));
                am.AddToRole(user.Id, "Root");
            }
        }
    }
}   
Second use
Int32.Parse(User.Identity.GetUserId()
every where it is needed.
Hightlight on UserManager instanciation
new UserManager<ApplicationUser, Int32>(new UserStore<
    ApplicationUser, 
    CustomRole, 
    Int32, 
    CustomUserLogin, 
    CustomUserRole, 
    CustomUserClaim
>(context));

jeudi 29 août 2013

Import from excel: the mixed colums issue

From the sas knowledge base I get some usefull information : TypeGuessRows

Basically TypeGuessRows is the number of rows explored by the driver to determine the type of the columns.By default it is set to 8.

I suggest to set it to 0, that is to explore all rows. This may lead to performance issue, but prevents data loss.
According to the cited article the keys are:
  1. HKEY_LOCAL_MACHINE/Software/Microsoft/Office/12.0/Access Connectivity Engine/Engines/Excel/TypeGuessRows
  2. HKEY_LOCAL_MACHINE/Software/Wow6432Node/Microsoft/Office/12.0/Access Connectivity Engine/Engines/Excel/TypeGuessRows
But I also find them :
  1. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\14.0\Access Connectivity Engine\Engines\Excel
  2. HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Jet\4.0\Engines\Excel
The best is to scan the register searching : TypeGuessRows.

lundi 25 mars 2013

Excecute SQL batch from C#

Two ways, extending two objects. For a SSMS like use, batchSeparator should be equal to go.

    public static class SomeExtensionsClass {
        public static void ExecuteBatchFromFile(this DataContext dc, String fileName, String batchSeparator) {
            StringBuilder sb = new StringBuilder();
            foreach (String sqlLine in File.ReadAllLines(fileName)) {
                if (sqlLine == batchSeparator) {
                    if (sb.Length != 0) {
                        dc.ExecuteCommand(sb.ToString());
                        sb.Remove(0, sb.Length); //On attend de passer en .Net 4 pour le .Clear
                    }
                } else {
                    sb.AppendLine(sqlLine);
                }
            }
            if (sb.Length != 0)
                dc.ExecuteCommand(sb.ToString());
        }

        public static void ExecuteBatchFromFile(this ObjectContext oc, String fileName, String batchSeparator) {
            StringBuilder sb = new StringBuilder();
            foreach (String sqlLine in File.ReadAllLines(fileName)) {
                if (sqlLine == batchSeparator) {
                    if (sb.Length != 0) {
                        oc.ExecuteStoreCommand(sb.ToString());
                        sb.Remove(0, sb.Length); //On attend de passer en .Net 4 pour le .Clear
                    }
                } else {
                    sb.AppendLine(sqlLine);
                }
            }
            if (sb.Length != 0)
                oc.ExecuteStoreCommand(sb.ToString());
        }
    }

lundi 21 novembre 2011

C# WPF, Dynamic Loading / Late Binding / Reflection with AvalonEdit

The point here is to optionnaly allow to use AvalonEdit (formerly known as Avalon) in an (wpf) application.


The basics

Specific using:
using System.IO;
using System.Reflection;
using System.Xml; //only for "the not so basic"
As you can see, none of them concerns AvanlonEdit...

When to Load :
String AvalonEditDllName = "ICSharpCode.AvalonEdit.dll";
if ( File.Exists(AvalonEditDllName) ) {/*...*/}

How to load:
Assembly u = Assembly.LoadFile(Path.GetFullPath(AvalonEditDllName));

What to instanciate:
Type tAvalonEditTextEditor = u.GetType("ICSharpCode.AvalonEdit.TextEditor");
if ( tAvalonEditTextEditor != null ) {/*...*/}

How to instanciate:
System.Windows.UIElement aeui = 
    (System.Windows.UIElement)Activator.CreateInstance(tAvalonEditTextEditor);

From now, you can use your System.Windows.UIElement in your WPF form just like this:
MainGrid.Children.Add(aeui);
where MainGrid is, for example, a System.Windows.Controls.Grid.

The basics of properties

Do you want line numbers ?
First let's look for the property of the type :
PropertyInfo propShowLineNumbers = 
    tAvalonEditTextEditor.GetProperty("ShowLineNumbers");
Then let's make the property true :
propShowLineNumbers.SetValue(aeui, true, null);

The not so basic of properties

And what about syntax hihgligting ?? Good question indeed !
Some more types and properties:
Type tAvalonEditHightingLoader = 
    u.GetType("ICSharpCode.AvalonEdit.Highlighting.Xshd.HighlightingLoader");
Type tAvalonEditHightingManager = 
    u.GetType("ICSharpCode.AvalonEdit.Highlighting.HighlightingManager");

PropertyInfo propSyntaxHighlighting = tAvalonEditTextEditor.GetProperty("SyntaxHighlighting");
PropertyInfo spropAEHMInstance = tAvalonEditHightingManager.GetProperty("Instance");

And the loading himself (I try to keep the variables consistant with the previous pieces of code):
String XshdFileName = "t-sql.xshd";
using ( XmlTextReader reader = new XmlTextReader(XshdFileName) ) {
    propSyntaxHighlighting.SetValue( //let's set the property of the text editor
        aeui,
        tAvalonEditHightingLoader.InvokeMember(
            "Load", //by loading the xshd file with HightingLoader.Load
            BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | 
                BindingFlags.InvokeMethod,
            null, null,
                   //with the following parameters
            new Object[] { reader, spropAEHMInstance.GetValue(null, null) }
                   //one of them being the static property
                   //HighlightingManager.Instance
        ),
        null
    );
 }

mercredi 2 novembre 2011

Sales Force and WCF

Hello,
The following is a 2 hours testing session resulting of the following sentence : "Our client wants to interface our Production tool with Sales Force...". Of course I heard of Sales Force before, but nothing more.
I assume that you have downloaded the wsdl file from your Sales Force Account.
Then you use the svcutil tool to generate your proxy class. Something like :
"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\x64\svcutil" *.wsdl /language:C#

From this point you should realise that svcutil gives you a cs file but also an app.config part to use in your project to configure the proxy class.
Then the following code should list, on the console, the Accounts of your Sales Force Application. In this code "Soap" is a "false friend" coming from my minimalistic svcutil command line.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

namespace sfBySoap {
  class Program {
    static void Main(string[] args) {
      try {
        SoapClient sfClient = new SoapClient();
        String sfLogin = "***@***.***";
        String sfPassword = "***";
        String sfSecurityToken = "***";
        LoginResult lr = sfClient.login(
          null, 
          sfLogin, 
          sfPassword + sfSecurityToken);
        Console.WriteLine("{0}\r\n{1}",
            lr.sessionId, 
            lr.serverUrl);
        SoapClient sc = new SoapClient(
            "Soap", 
            new EndpointAddress(new Uri(lr.serverUrl)));

        SessionHeader sh = new SessionHeader();
        sh.sessionId = lr.sessionId;

        QueryResult qr = sc.query(
              sh, //SessionHeader
              null, //QueryOptions
              null, //MruHeader
              null, //PackageVersion
              "select NAME, DESCRIPTION, TYPE, " +
                  "CREATEDBYID from Account");

        while (true) {
          foreach (Account a in qr.records) {
              Console.WriteLine("{0} - {1}\r\n    :{2}",
                  a.Name,
                  a.Type,
                  a.Description);
          }

          if (qr.done) {
              break;
          } else {
              qr = sc.queryMore(sh, null, qr.queryLocator);
          }
        }

        //sfClient.logout();
        sc.Close();
        sfClient.Close();
      } catch (Exception ex) {
          ExToConsole(ex);
      }
    }

    static void ExToConsole(Exception ex) {
        if (ex != null) {
            Console.WriteLine(ex.Message);
            ExToConsole(ex.InnerException);
        }
    }
  }
}

Here it is.... you are connected to Sales Force.

vendredi 2 septembre 2011

C# MongoDb - the really basics

I came from http://www.mongodb.org/display/DOCS/CSharp+Driver+Tutorial#CSharpDriverTutorial-InsertBatchmethod, where I spent a little hour.

I found that a more explicit sample was missing. So here it is the C# version of the article.

The real question I'm trying to answer is : how to map a POCO to MongoDb.

using System;

using MongoDB.Driver;
using MongoDB.Bson;
using MongoDB.Bson.Serialization;

namespace mdbBacASable {
  class Program {
    static void Main(String[] args) {
      try {
        String connectionString = 
            "mongodb://localhost:27017";
        MongoServer mdbServer = 
            MongoServer.Create(connectionString);
        MongoDatabase mdbTest = 
            mdbServer.GetDatabase("test");
        MongoCollection<BsonDocument> bsDocBooks = 
          mdbTest.GetCollection<BsonDocument>("books");
        bsDocBooks.RemoveAll();
        BsonDocument bsDocBook = new BsonDocument {
          { "Author", "Ernest Hemingway" },
          { "Title", "For Whom the Bell Tolls" }
        };
        
        bsDocBooks.Insert(bsDocBook);
        BsonDocument[] batch = {
          new BsonDocument {
            { "Author", "Kurt Vonnegut" },
            { "Title", "Cat's Cradle" }
          },
          new BsonDocument {
            { "Author", "Kurt Vonnegut" },
            { "Title", "Slaughterhouse-Five" }
          }
        };
        bsDocBooks.InsertBatch(batch);
          
        //-----------------------------------------------
        
        BsonClassMap.RegisterClassMap<Book>(cm => {
          cm.AutoMap();
          cm.SetIdMember(cm.GetMemberMap(c => c.Id));
        });
        MongoCollection<Book> Books = 
            mdbTest.GetCollection<Book>("books");
        Book oBook = new Book() { 
          Author = "JRR Tolkien", 
          Title = "Lord of the Ring" };
        Books.Insert(oBook);

        //----------------------------------------------
        
        Book Book = Books.FindOne();
        Console.WriteLine("{0} : {1}", 
          Book.Author, Book.Title);

        Console.WriteLine("\r\n------------------------\r\n");

        foreach ( Book b in Books.FindAll() ) {
          Console.WriteLine("{0} : {1} : {2}", 
            b.Id, b.Author, b.Title);
        }
      } catch (Exception ex) {
        Console.WriteLine(ex.Message);
      }
    }
  }

  public class Book {
    public ObjectId Id { get; set; }
    public String Author { get; set; }
    public String Title { get; set; }
  }
}