1

I need to restrict the number of customer bo's returned from the database as I am searching for a partial customer name and at the moment I get over 600 bo's when searching for 'a'. I would like to restrict this to 20. My code at the moment is

    public IEnumerable<Customer> FindCustomers(string partialCustomerName)
    {
        if (string.IsNullOrEmpty(partialCustomerName)) 
          throw new ArgumentException("partialCustomerName must be at least one character long");
        var criteria = Criteria.Create<Customer, string>(cust =>   cust.CustomerName, Criteria.ComparisonOp.Like, partialCustomerName + "%");
        return Broker.GetBusinessObjectCollection<Customer>(criteria);
    }
Andrew
  • 5,215
  • 1
  • 23
  • 42

3 Answers3

2

I cannot test this right now but you should be able to this by using the LoadWithLimit() method. The totalRecords variable will hold the number of total results found in case you want to include some info like "Showing 20 of totalRecords results.".

public IEnumerable<Customer> FindCustomers(string partialCustomerName)
{
    if (string.IsNullOrEmpty(partialCustomerName)) 
      throw new ArgumentException("partialCustomerName must be at least one character long");

    var criteria = Criteria.Create<Customer, string>(cust =>   cust.CustomerName, Criteria.ComparisonOp.Like, partialCustomerName + "%");
    int totalRecords;
    return Broker.GetBusinessObjectCollection<Customer>().LoadWithLimit(criteria, 0, 20, ref totalRecords);
}
Till
  • 3,084
  • 17
  • 18
1

Till is on the right track there, but did not give the correct syntax. The broker is used to load collections from the current Data Accessor, not for creating new ones. So the code would then be:

public IEnumerable<Customer> FindCustomers(string partialCustomerName)
{
    if (string.IsNullOrEmpty(partialCustomerName)) 
      throw new ArgumentException("partialCustomerName must be at least one character long");

    var criteria = Criteria.Create<Customer, string>(cust =>   cust.CustomerName, Criteria.ComparisonOp.Like, partialCustomerName + "%");
    int totalRecords;
    var col = new BusinessObjectCollection<Customer>();
    col.LoadWithLimit(criteria, "CustomerName", 0, 20, ref totalRecords);
    return col;
}

That should do it! Please award the answer to Till, not me. He did the most research. I just corrected the syntax :)

EDIT: After comments below about the ugly API, I will include suggested changes to the method to make it look cleaner (Thanks for your suggestion @GloryDev):

public IEnumerable<Customer> FindCustomers(string partialCustomerName)
{
    if (string.IsNullOrEmpty(partialCustomerName)) 
      throw new ArgumentException("partialCustomerName must be at least one character long");
    var col = new BusinessObjectCollection<Customer>();
    col.LoadWithLimit("CustomerName Like " + partialCustomerName + "%", "CustomerName", 20);
    return col;
}

The Second parameter is the field to order by, which is necessary for a fetch with limits to make any sense. Hope this helps.

Mark Whitfeld
  • 6,500
  • 4
  • 36
  • 32
  • Excellent just what I was looking for. – Andrew Jun 02 '11 at 14:40
  • Yes I prefer the one in my Answer below. This Create.Criteria stuff using lambdas is very new and is as I understand it this is what is being used behind the scenes in the Linq to Habanero. I am not sure if this is intended to be the API. – GloryDev Jun 02 '11 at 19:05
  • I agree with @Chris on this. This usage of the API is quite abstract and doesn't look clean at all. The lambda stuff is really intended for parsing full lambda expressions, not just getting the property name. I have added a cleaner version of the above method at the end of my post which includes the suggestion by @GloryDev with a slight modification. – Mark Whitfeld Jun 03 '11 at 08:43
  • and @GloryDev honestly the Criteria part is OK, it's not great (with the weird way to define the operation), it's the core API that is terrible `new BusinessObjectCollection();`, `col.LoadWithLimit` these things are pure WTFs, seeing the factory method below is even a bigger WTF `Broker.GetBusinessObjectCollection().LoadWithLimit(` Just about anytime an API requires you to use a collection class they created it shows architect failure on their part. But with an ORM it's one of the gray areas, since they could trade off needing to do dynamic proxies perhaps – Chris Marisic Jun 03 '11 at 12:43
1

Andrew You could always do this looks a bit neater but does involve parsing the CustomerName.

        var totalRecords = 0;
        Broker.GetBusinessObjectCollection<Customer>("CustomerName Like partialCustomerName ", "CustomerName", 0, 20, out totalRecords);
GloryDev
  • 670
  • 5
  • 8