so, pretty pointless post, but someone may stumble upon it sometime and it may help you so here it is..
had my PS3 for well over a couple of years and been playing on the same tv in HD all the time.. all of a sudden when i loaded games the screen just stayed black. i spoke to sony and htey sent me a replacement for £130 and i exchanged my old one.. got the new one, exactly the same problem, it turned out that it was the resoultion the PS3 was setting itself to. I have no idea why this happened on the same tv as i had always been playing on, but anyway, all i had to do in the end was take off the tick in the 1080 checkbox in display settings and it worked, and sony are refunding my £130.. happy days..
Paul
Friday, 25 June 2010
Sunday, 20 June 2010
Learn NHibernate Lesson 5 - Modelling foreign key relationships
disclaimer - at the moment, this post is in note format from a workshop I did, I need to it clean up, and add grammar
5. Modelling foreign key relationships
a one to many relationship between customer and orders in a database could be said to be, or coded like:[csharp]
class Customer {
private IList<Order> _orders;
class Order {
private Customer customer;
[/csharp]
sql may be:[sql]
from parent to child:
select * from customer inner join order on c.customerid on o.customerid where c.customerid = (id of the customer)
from child to parent:
select * from order inner join customer on o.customerid on c.customerid where o.orderid = (id of the order)
[/sql]
mapping files
supported relationships
one-to-one
one-to-many
many-to-one
many-to-many
not all orm software support all these, especially many to many
mappping files also control cascade updates and cascade deletes
you can control navigation between parents and children in mapping files
NHibernate collection types
Bag
collection of objects where each element can repeat (implemented as an IList or IList of <T>) { 1, 2, 3, 3, 3 }
Set
collection of object where each element must be unique (same as a true mathematical set) (implemented as an ISet or ISet<T>)
ISet is in Iesi.Collections.dll (not in .Net libraries)
List
collection of object with integer indicies (impleneted as an ArrayList or List<T>
Map
collection of key value pairs (implemented as IDictionary or hashtable)
Collection Mappings
defines:
collection type (bag, set..)
cardinality (one to many etc..)
cascasde behaviour
who is responsible for updating (inverse = true, child is responsible)
Child collection mapping define very little, usually just a pointer to support navigation back to the parent and the cardinality back to the parent
deep object graphs casue a lot of trouble, recursive relationships due to self referetial modelling (orders on customer and customer on orders)
Lazy Loading
the name doesnt exaplin exactly whats happenning
it should be named 'delayed laoding' or 'load on demand'
implentation is The Proxy Pattern
how it works
orders colletion on customers would create a proxy object, so it doesnt actually go and get the orders, but it knows how to. so if we dont interact with the orders collection, it will never be loaded. as soon as we do, the proxy object will be invoked and it will go off tothe dband get the orders..
after that, the proxy object goes away, the colection will now point to the correct orders object
the same thing is true in the reverse direction, each order object on the collection will contain proxy objects to the customer. however this will not actually go to the db as nhibe will check the session fo rthe customer we need, and it will already be there as the parent that loaded the orders collection
our order class willl look like this: //excuse the lack of settters and getters this is just an example[csharp]
public class Order {
public int orderid;
public DateTIme Order;
//now, although we are only referencing the customer and an int, or id in the database, we do not model this as an int, customerid, we actually model it as a Customer object
public Customer customer;
//in our customers class we now have
public ISet<Order> _orders;
[/csharp]
mapping the order class
now, in our customer hbm.xml mapping file, we add the following:[xml]
<set name="Orders" table="`Order`" generic="true" inverse="true"> //inverse=true the child object is responsible for maintaining the relationship back to the customer
<key column="Customer" />
<one-to-many class="DataTransfer.Order, DataTransfer" />
</set>
[/xml]
now, we create a new Order hbm.xml Mapping file..[xml]
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembley="DataTransfer" namespace="DataTransfer">
<class name="DataTransfer.Order, DataTransfer" table="`Order`"> (Namepsapce.TypeName, Namespace)
<id name="OrderId" column="OrderId" type="Int32" unsaved-value="0">
<generator></generator>
</id>
<property name="Name" column="Name" type="string" length="50" not-null="false"></property>
<property name="OrderDate" column="OrderDate" type="DateTime" not-null="true"></property>
<many-to-one name="Customer" column="Customer" not-null="true" class="DataTransfer.Customer, DataTransfer" />
</class>
</hibernate-mapping>
[/xml]
remember to change the build action for new hbm.xml files to embedded resource..
NOTE, in NHibe, if you are using db keywords, like table or order, instead of using [table] or [order] we use the back tick like so: `Order`
Testing the mapping files
understanding lazy loading
looking at a GetCustomerById()
if we look at the orders in the loaded customer, we'll get an nhibe exception, no session, why? beacsue we have wrapped our session in a using statment
so when the object tries to hydrate the orders object, there is no session
so for lazy loading you must make sure you have not disposed of the session before the lazy loading has worked
you could change the lazy attribute in the set tag in customers mapping file to false : lazy="false"
you could make another method called get customers and orders by custoemr id that does not dispose of the session
we will look at better ways of handling session lifecycle in later lessons
now if we make the new method[csharp]
public Customer GetCustomersAndOrdersByCustomerId(int id)
{
Customer customer = session.Get<Customer>(id);
//fill out (load) the orders and dont load as proxy
NHibernateUtil.Initialize(customer.Orders); // util is in iesi.collections.dll
}
[/csharp]
a one to many relationship between customer and orders in a database could be said to be, or coded like:[csharp]
class Customer {
private IList<Order> _orders;
class Order {
private Customer customer;
[/csharp]
sql may be:[sql]
from parent to child:
select * from customer inner join order on c.customerid on o.customerid where c.customerid = (id of the customer)
from child to parent:
select * from order inner join customer on o.customerid on c.customerid where o.orderid = (id of the order)
[/sql]
mapping files
supported relationships
one-to-one
one-to-many
many-to-one
many-to-many
not all orm software support all these, especially many to many
mappping files also control cascade updates and cascade deletes
you can control navigation between parents and children in mapping files
NHibernate collection types
Bag
collection of objects where each element can repeat (implemented as an IList or IList of <T>) { 1, 2, 3, 3, 3 }
Set
collection of object where each element must be unique (same as a true mathematical set) (implemented as an ISet or ISet<T>)
ISet is in Iesi.Collections.dll (not in .Net libraries)
List
collection of object with integer indicies (impleneted as an ArrayList or List<T>
Map
collection of key value pairs (implemented as IDictionary or hashtable)
Collection Mappings
defines:
collection type (bag, set..)
cardinality (one to many etc..)
cascasde behaviour
who is responsible for updating (inverse = true, child is responsible)
Child collection mapping define very little, usually just a pointer to support navigation back to the parent and the cardinality back to the parent
deep object graphs casue a lot of trouble, recursive relationships due to self referetial modelling (orders on customer and customer on orders)
Lazy Loading
the name doesnt exaplin exactly whats happenning
it should be named 'delayed laoding' or 'load on demand'
implentation is The Proxy Pattern
how it works
orders colletion on customers would create a proxy object, so it doesnt actually go and get the orders, but it knows how to. so if we dont interact with the orders collection, it will never be loaded. as soon as we do, the proxy object will be invoked and it will go off tothe dband get the orders..
after that, the proxy object goes away, the colection will now point to the correct orders object
the same thing is true in the reverse direction, each order object on the collection will contain proxy objects to the customer. however this will not actually go to the db as nhibe will check the session fo rthe customer we need, and it will already be there as the parent that loaded the orders collection
our order class willl look like this: //excuse the lack of settters and getters this is just an example[csharp]
public class Order {
public int orderid;
public DateTIme Order;
//now, although we are only referencing the customer and an int, or id in the database, we do not model this as an int, customerid, we actually model it as a Customer object
public Customer customer;
//in our customers class we now have
public ISet<Order> _orders;
[/csharp]
mapping the order class
now, in our customer hbm.xml mapping file, we add the following:[xml]
<set name="Orders" table="`Order`" generic="true" inverse="true"> //inverse=true the child object is responsible for maintaining the relationship back to the customer
<key column="Customer" />
<one-to-many class="DataTransfer.Order, DataTransfer" />
</set>
[/xml]
now, we create a new Order hbm.xml Mapping file..[xml]
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembley="DataTransfer" namespace="DataTransfer">
<class name="DataTransfer.Order, DataTransfer" table="`Order`"> (Namepsapce.TypeName, Namespace)
<id name="OrderId" column="OrderId" type="Int32" unsaved-value="0">
<generator></generator>
</id>
<property name="Name" column="Name" type="string" length="50" not-null="false"></property>
<property name="OrderDate" column="OrderDate" type="DateTime" not-null="true"></property>
<many-to-one name="Customer" column="Customer" not-null="true" class="DataTransfer.Customer, DataTransfer" />
</class>
</hibernate-mapping>
[/xml]
remember to change the build action for new hbm.xml files to embedded resource..
NOTE, in NHibe, if you are using db keywords, like table or order, instead of using [table] or [order] we use the back tick like so: `Order`
Testing the mapping files
understanding lazy loading
looking at a GetCustomerById()
if we look at the orders in the loaded customer, we'll get an nhibe exception, no session, why? beacsue we have wrapped our session in a using statment
so when the object tries to hydrate the orders object, there is no session
so for lazy loading you must make sure you have not disposed of the session before the lazy loading has worked
you could change the lazy attribute in the set tag in customers mapping file to false : lazy="false"
you could make another method called get customers and orders by custoemr id that does not dispose of the session
we will look at better ways of handling session lifecycle in later lessons
now if we make the new method[csharp]
public Customer GetCustomersAndOrdersByCustomerId(int id)
{
Customer customer = session.Get<Customer>(id);
//fill out (load) the orders and dont load as proxy
NHibernateUtil.Initialize(customer.Orders); // util is in iesi.collections.dll
}
[/csharp]
Thursday, 17 June 2010
Learn NHibernate Lesson 4 - Transactions and Concurrency
disclaimer - at the moment, this post is in note format from a workshop I did, I need to it clean up, and add grammar
4. Transactions and Concurrency
nhiberate provides its own ITransaction abstraction
the goal of nhibe is to abstract the choice of databse engine for you. so you dont need to worry about how the db imlements transactions, nhibe will do it for you.
Transaction Pattern
ask the ISession to begin a transaction
do some work
commit or rollback the transaction[csharp]
ITransaction tx = session.BeginTransaction();
//do some work
tx.Commit();
// or tx.Rollback();
[/csharp]
real world is a bit more complex[csharp]
using(ITransaction tx = session.BeginTransaction())
{
try {
//do some work
tx.Commit();
}
catch(NHibernateException) {
tx.Rollback();
throw;
}
}
[/csharp]
when shold you use transactions? Aways! - even on reads (queries)
you have no idea why a db operation may have failed, so instead or worrying, just implement transactions..
before we start we need a refactor of our dataaccess layer. we have a private global session
this is not a great design strategy
the session is not made to be hung on to for a long time
it is non thread safe use once and throw away
the session factory however is much stronger use once
so.. we change the private ISession to an ISessionFactory[csharp]
public class DataAccessProvider
{
private ISessionFactory sessionFactory;
//we now call the getsession in the constructor to the class..
public DataAccessProvider ()
{
sessionFactory = GetSessionFactory();
}
private static ISession GetSession()
{
return sessionFactory.OpenSession();
}
private static ISession GetSessionFactory()
{
return (new Configuration()).Configure().BuildSessionFactory();
}
[/csharp]
now our methods become like:[csharp]
public void AddCustomer(Customer customer)
{
ISession session = GetSession();
session.Save(customer); //save will return an object that represents the primary key of that object in the database
session.Flush();
}
[/csharp]
now each method will use its own copy of the session (not perfect, we will move on again later in the lessons..[csharp]
[test]
[ExpectedException(typeof(NHibernate.HibernateException))]
public void DeleteCustomerCanThrowExceptionOnFail()
{
Customer c = GetFirstCustomerWithOrders();
provider.DeleteCustomer(c);
}
[/csharp]
now, how can we refactor the delete customer method to take advantage of transactions..[csharp]
public void DeleteCustomer(Customer c)
{
using(ISession session = GetSession()) {
using(ITransaction tx = session.BeginTransaction()) {
try {
session.Delete(c);
session.Flush();
tx.Commit();
}
catch(NHibernateException) {
tx.Rollback();
throw;
}
}
}
}
[/csharp]
Concurrency
what does it mean? 2 or more users may be editing hte same data at the same time..
this especially happens in a disconnected-data world
types of concurrency:
Pessimistic concurrency
something in the overall system is responsible for actively blocking operations that could result in data-synchronisation conflicts
Pessimistic (assume something is going to go badly and actively block it from happening)
usually accomplished by exclusive locks approach - Expensive!
Optimsitic Concurrency
assumes no operations that could result in data-synchronisation conflicts will occur and is reposinsible for reacting properly when they do
similar to edit, merge, comit with todays source control, unlike old source control with exclusive locks..
NHibernate Optimistic Concurrency
several approaches
in the approriate hbm.xml mapping file, add a <version> element (implementation of row versioning)
or a <timestamp> element (implementation of timestamp tracking)
and several others..
in general, row versioning is preferred
the version tag must precede any property tags in the mapping file
assuming we have added an integer proeprty called version to customer class[xml]
<version name="Version" column="Version" type="integer" unsaved-value="0" />
[/xml]
now in the database, when you add the version column, no nulls, default value is 1
nhiberate provides its own ITransaction abstraction
the goal of nhibe is to abstract the choice of databse engine for you. so you dont need to worry about how the db imlements transactions, nhibe will do it for you.
Transaction Pattern
ask the ISession to begin a transaction
do some work
commit or rollback the transaction[csharp]
ITransaction tx = session.BeginTransaction();
//do some work
tx.Commit();
// or tx.Rollback();
[/csharp]
real world is a bit more complex[csharp]
using(ITransaction tx = session.BeginTransaction())
{
try {
//do some work
tx.Commit();
}
catch(NHibernateException) {
tx.Rollback();
throw;
}
}
[/csharp]
when shold you use transactions? Aways! - even on reads (queries)
you have no idea why a db operation may have failed, so instead or worrying, just implement transactions..
before we start we need a refactor of our dataaccess layer. we have a private global session
this is not a great design strategy
the session is not made to be hung on to for a long time
it is non thread safe use once and throw away
the session factory however is much stronger use once
so.. we change the private ISession to an ISessionFactory[csharp]
public class DataAccessProvider
{
private ISessionFactory sessionFactory;
//we now call the getsession in the constructor to the class..
public DataAccessProvider ()
{
sessionFactory = GetSessionFactory();
}
private static ISession GetSession()
{
return sessionFactory.OpenSession();
}
private static ISession GetSessionFactory()
{
return (new Configuration()).Configure().BuildSessionFactory();
}
[/csharp]
now our methods become like:[csharp]
public void AddCustomer(Customer customer)
{
ISession session = GetSession();
session.Save(customer); //save will return an object that represents the primary key of that object in the database
session.Flush();
}
[/csharp]
now each method will use its own copy of the session (not perfect, we will move on again later in the lessons..[csharp]
[test]
[ExpectedException(typeof(NHibernate.HibernateException))]
public void DeleteCustomerCanThrowExceptionOnFail()
{
Customer c = GetFirstCustomerWithOrders();
provider.DeleteCustomer(c);
}
[/csharp]
now, how can we refactor the delete customer method to take advantage of transactions..[csharp]
public void DeleteCustomer(Customer c)
{
using(ISession session = GetSession()) {
using(ITransaction tx = session.BeginTransaction()) {
try {
session.Delete(c);
session.Flush();
tx.Commit();
}
catch(NHibernateException) {
tx.Rollback();
throw;
}
}
}
}
[/csharp]
Concurrency
what does it mean? 2 or more users may be editing hte same data at the same time..
this especially happens in a disconnected-data world
types of concurrency:
Pessimistic concurrency
something in the overall system is responsible for actively blocking operations that could result in data-synchronisation conflicts
Pessimistic (assume something is going to go badly and actively block it from happening)
usually accomplished by exclusive locks approach - Expensive!
Optimsitic Concurrency
assumes no operations that could result in data-synchronisation conflicts will occur and is reposinsible for reacting properly when they do
similar to edit, merge, comit with todays source control, unlike old source control with exclusive locks..
NHibernate Optimistic Concurrency
several approaches
in the approriate hbm.xml mapping file, add a <version> element (implementation of row versioning)
or a <timestamp> element (implementation of timestamp tracking)
and several others..
in general, row versioning is preferred
the version tag must precede any property tags in the mapping file
assuming we have added an integer proeprty called version to customer class[xml]
<version name="Version" column="Version" type="integer" unsaved-value="0" />
[/xml]
now in the database, when you add the version column, no nulls, default value is 1
Wednesday, 9 June 2010
Learn NHibernate Lesson 3 - Insert, Update and Deletes
disclaimer - at the moment, this post is in note format from a workshop I did, I need to it clean up, and add grammar
3. Insert, Update and Deletes
A Unit of work is an isolated area withing which i cna perform one or more operations. They are either commited or abandoned / rolled back as one.
As of yet we have not used nhibe to change any data. Query only. if no changes, then no commit or rollback..
Insert Pattern is simple
New up an object, ask the ISession to save it, Flush the session (flush is the commit method)[csharp]
Customer customer = new Customer();
session.save(customer);
session.Flush();
[/csharp]
Delete pattern is simple[csharp]
Customer customer = provider.GetCustomerById(1);
session.Delete(customer);
session.Flush();
[/csharp]
Update pattern
have an object
change a property
ask the session to update it
flush the sesison
primary annoyance is that you have to keep track of what objects have chnaged.. but there is a solution, ISession is able to keep track of what object are new and updated so we can call session.SaveOrUpdate and NHibe will perform the correct action. Calling saveorupdate will cause NHibe to go through some checking operatios such as:
is the object in session? if not there, call implicit Save(object);
if its there, see it the object has changed, if it has, call implicit update(object)..[csharp]
public void AddCustomer(Customer customer)
{
session.Save(customer); //save will return an object that represents the primary key of that object in the database
session.Flush();
}
[/csharp]
so you can get new primary key by saying[csharp]
int newId = (int)session.Save(customer);
[test]
public void CanAddCustomer()
{
Customer customer = new Customer() { Firstname = "steve", Lastname = "smith" };
int newId = provider.AddCustomer(customer);
Customer testCustomer = provider.GetCustomerById(newId);
Assert.IsNotNull(testCustomer);
}
public void DeleteCustomer(Customer customer)
{
session.Delete(customer);
session.Flush();
}
[test]
public void CanDeleteCustomer()
{
Customer customer = provider.GetCustomerById(1);
provider.DeleteCustomer(customer);
Customer testCustomer = provider.GetCustomerById(1);
Assert.IsNull(testCustomer);
}
[/csharp]
A Unit of work is an isolated area withing which i cna perform one or more operations. They are either commited or abandoned / rolled back as one.
As of yet we have not used nhibe to change any data. Query only. if no changes, then no commit or rollback..
Insert Pattern is simple
New up an object, ask the ISession to save it, Flush the session (flush is the commit method)[csharp]
Customer customer = new Customer();
session.save(customer);
session.Flush();
[/csharp]
Delete pattern is simple[csharp]
Customer customer = provider.GetCustomerById(1);
session.Delete(customer);
session.Flush();
[/csharp]
Update pattern
have an object
change a property
ask the session to update it
flush the sesison
primary annoyance is that you have to keep track of what objects have chnaged.. but there is a solution, ISession is able to keep track of what object are new and updated so we can call session.SaveOrUpdate and NHibe will perform the correct action. Calling saveorupdate will cause NHibe to go through some checking operatios such as:
is the object in session? if not there, call implicit Save(object);
if its there, see it the object has changed, if it has, call implicit update(object)..[csharp]
public void AddCustomer(Customer customer)
{
session.Save(customer); //save will return an object that represents the primary key of that object in the database
session.Flush();
}
[/csharp]
so you can get new primary key by saying[csharp]
int newId = (int)session.Save(customer);
[test]
public void CanAddCustomer()
{
Customer customer = new Customer() { Firstname = "steve", Lastname = "smith" };
int newId = provider.AddCustomer(customer);
Customer testCustomer = provider.GetCustomerById(newId);
Assert.IsNotNull(testCustomer);
}
public void DeleteCustomer(Customer customer)
{
session.Delete(customer);
session.Flush();
}
[test]
public void CanDeleteCustomer()
{
Customer customer = provider.GetCustomerById(1);
provider.DeleteCustomer(customer);
Customer testCustomer = provider.GetCustomerById(1);
Assert.IsNull(testCustomer);
}
[/csharp]
Tuesday, 8 June 2010
Building Visual Studio solutions from a right click in windows explorer
Heres how to add build to the context menu of a sln file..
note: you only need the tool for vista.. xp and 7 let you change and add context menu operations in the folder options->file type menu..
so, if you are on vista, download from http://www.creativelement.com/powertools/#download
when you start it for first time, check the "Edit File Type Associations" box, theres loads of other good stuff but ill let you discover
now right click the sln file and select edit file type
click ADD
type Build (debug) for the top text box
then paste this in second box (which application to use)
c:\WINDOWS\system32\cmd.exe
and this in the final box (command line op)
/k C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe "%1" /p:Configuration=Debug /t:Rebuild
Now go back to the sln file and youll be able to right click and build..
Have fun
note: you only need the tool for vista.. xp and 7 let you change and add context menu operations in the folder options->file type menu..
so, if you are on vista, download from http://www.creativelement.com/powertools/#download
when you start it for first time, check the "Edit File Type Associations" box, theres loads of other good stuff but ill let you discover
now right click the sln file and select edit file type
click ADD
type Build (debug) for the top text box
then paste this in second box (which application to use)
c:\WINDOWS\system32\cmd.exe
and this in the final box (command line op)
/k C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe "%1" /p:Configuration=Debug /t:Rebuild
Now go back to the sln file and youll be able to right click and build..
Have fun
Monday, 7 June 2010
Learn NHibernate Lesson Part 2 - More Query Methods and Syntaxes
disclaimer - at the moment, this post is in note format from a workshop I did, I need to it clean up, and add grammar
2 - Part 2 More Query Methods and Syntaxes
first a refactor.. up until now we have been getting a session in every dataaccess layer method. we dont want to be doing this as each time we get teh session we are connecting to the db, and wiring up anything else needed.. a waste.. so, we'll start by making session a private member on the dataaccess layer.[csharp]
public class DataAccessProvider
{
private ISession session;
//we now call the getsession in the constructor to the class..
public DataAccessProvider ()
{
session = GetSession();
}
//now methods will look like the following:
public IList<Customer> GetCustomerByFirstName(string firstname)
{
return session.CreateQuery("select from Customer c whre c.Firsname='" + firstname + "'").List<Customer>();
}
[/csharp]
getting distinct in HQL[csharp]
public IList<string> GetDistinctCustomerFirstnames()
{
return session.CreateQuery"select distinct c.Firstname from Customer c").List<string>();
}
[test]
public void CanGetDistinctCustomerFirstnames()
{
IList<string> firstnames;
provider.GetDistinctCustomerFirstnames();
IList<string> foundfirstnames = new List<string>();
foreach (string fn in firstnames)
{
if(foundFirstnames.Count != 0)
Assert.IsFalse(foundFirstNames.Contains(fn));
foundFirstNames.Add(fn);
}
}
[/csharp]
refactor test to use lambda expressions..[csharp]
[test]
public void CanGetDistinctCustomerFirstnames()
{
IList<string> firstnames;
provider.GetDistinctCustomerFirstnames();
foreach (string fn in firstnames)
{
Assert.AreEqual(1, firstnames.Count<string>(x => x == fn));
}
}
//GetDistinctCustomerFirstnames using criteria
public IList<string> GetDistinctCustomerFirstnames()
{
return session.CreateCrtieria<Customer>
.SetProjection(Projections.Distinct(Projections.Property("Firstname")))
.List<string>();
}
[/csharp]
getting ordered names through HQL[csharp]
public IList<string> GetOrderedCustomerFirstnames()
{
return session.CreateQuery<Customer>("select from Customer c order by c.Firstname").List<Customer>();
.List<string>();
}
[/csharp]
getting ordered names through Criteria[csharp]
public IList<string> GetOrderedCustomerFirstnames()
{
return session.CreateCritera<Customer>
.AddOrder(new Order("Firstname", true))
.List<string>();
}
[/csharp]
getting counted names through HQL[csharp]
public IList<object[]> GetCountedCustomerFirstnames()
{
return session.CreateQuery<Customer>("select c.Firstname, count(c.Firstname) from Customer c group by c.Firstname").List<object[]>();
.List<string>();
}
[test]
public void CanGetCountedCustomerFirstnames()
{
IList<object[]> firstnameCounts = provider.GetCountedCustomerFirstnames();
Dictionary<String, int> expectedCounts = new Dictionary<string, int>();
expectedCounts.Add("steve", 3);
expectedCounts.Add("mike", 1);
foreach(object[] item in firstnameCounts)
{
Assert.AreEqual(expectedCounts[item[0].ToString()], item[1]);
}
}
[/csharp]
first a refactor.. up until now we have been getting a session in every dataaccess layer method. we dont want to be doing this as each time we get teh session we are connecting to the db, and wiring up anything else needed.. a waste.. so, we'll start by making session a private member on the dataaccess layer.[csharp]
public class DataAccessProvider
{
private ISession session;
//we now call the getsession in the constructor to the class..
public DataAccessProvider ()
{
session = GetSession();
}
//now methods will look like the following:
public IList<Customer> GetCustomerByFirstName(string firstname)
{
return session.CreateQuery("select from Customer c whre c.Firsname='" + firstname + "'").List<Customer>();
}
[/csharp]
getting distinct in HQL[csharp]
public IList<string> GetDistinctCustomerFirstnames()
{
return session.CreateQuery"select distinct c.Firstname from Customer c").List<string>();
}
[test]
public void CanGetDistinctCustomerFirstnames()
{
IList<string> firstnames;
provider.GetDistinctCustomerFirstnames();
IList<string> foundfirstnames = new List<string>();
foreach (string fn in firstnames)
{
if(foundFirstnames.Count != 0)
Assert.IsFalse(foundFirstNames.Contains(fn));
foundFirstNames.Add(fn);
}
}
[/csharp]
refactor test to use lambda expressions..[csharp]
[test]
public void CanGetDistinctCustomerFirstnames()
{
IList<string> firstnames;
provider.GetDistinctCustomerFirstnames();
foreach (string fn in firstnames)
{
Assert.AreEqual(1, firstnames.Count<string>(x => x == fn));
}
}
//GetDistinctCustomerFirstnames using criteria
public IList<string> GetDistinctCustomerFirstnames()
{
return session.CreateCrtieria<Customer>
.SetProjection(Projections.Distinct(Projections.Property("Firstname")))
.List<string>();
}
[/csharp]
getting ordered names through HQL[csharp]
public IList<string> GetOrderedCustomerFirstnames()
{
return session.CreateQuery<Customer>("select from Customer c order by c.Firstname").List<Customer>();
.List<string>();
}
[/csharp]
getting ordered names through Criteria[csharp]
public IList<string> GetOrderedCustomerFirstnames()
{
return session.CreateCritera<Customer>
.AddOrder(new Order("Firstname", true))
.List<string>();
}
[/csharp]
getting counted names through HQL[csharp]
public IList<object[]> GetCountedCustomerFirstnames()
{
return session.CreateQuery<Customer>("select c.Firstname, count(c.Firstname) from Customer c group by c.Firstname").List<object[]>();
.List<string>();
}
[test]
public void CanGetCountedCustomerFirstnames()
{
IList<object[]> firstnameCounts = provider.GetCountedCustomerFirstnames();
Dictionary<String, int> expectedCounts = new Dictionary<string, int>();
expectedCounts.Add("steve", 3);
expectedCounts.Add("mike", 1);
foreach(object[] item in firstnameCounts)
{
Assert.AreEqual(expectedCounts[item[0].ToString()], item[1]);
}
}
[/csharp]
Saturday, 5 June 2010
Creating an iPhone Distribution
Requirements:
- A distribution provisioning profile will need to be installed prior to creating a build.
- To follow these steps, you must have the All-in-One layout set in the General tab of the Xcode Preferences.
Step #1 Create Distribution Configuration
- Select the Project Name in Xcode (see below)
- Right click and choose Get Info dialog (or enter Command I)
- Select Configuration tab
- Click on Release in the list of configurations and select Duplicate from the options along the bottom
- Name the new configuration Distribution
- Close the window
Step #2 Set Target Information
- Select the Target (see below)
- Right click and choose Get Info dialog
- Select Build tab
- Choose Distribution from Configuration drop-down
- In the Architectures section in the list of settings, choose a Base SDK (e.g. Device - iPhone OS 2.2.1)
- From the Code Signing Section, under Code Signing Identity, choose the appropriate profile (e.g. Ad Hoc or Distribution Profile)
- Select Properties tab
- Set Executable name (e.g. theAstrologerFree)There is a default value here: ${EXECUTABLE_NAME} which will also work for most projects
- Set Identifier to com.domain.application-name (e.g. com.3SixtySoftware.theAstrologerFree)There is a default value here: com.yourcompany.${PRODUCT_NAME:identifier} which you may work for your project. If you run into errors or conflicts with other applications try replacing${PRODUCT_NAME:identifier} with a unique string that represents your application nameSet Version # (e.g. 1.1)
- Set Icon File to Icon.png
- • Make sure you have an icon that is 57x57 pixels, with the name Icon.png in the project
- Close the window
Visit iPhoneDeveloperTips.com for more Tips and Tricks
Step #3 Set Active Configuration
- Select the Debug workspace button (see below) Select the Project workspace button (the button to the left of Debug)
- From the drop-down (upper left) choose:
- Choose the Device Setting you plan to target under Active SDK (e.g. Device - iPhone OS 2.2.1)
- Choose Distribution as the Active Configuration
If creating an Ad Hoc Distribution:
- Create new file (Command N), select Code Signing, choose Entitlements, click Next
- Name the file Entitlements.plist
- Uncheck the get-task-allow button
- Save file
- Make sure the file is at the root of project hierarchy (e.g. drag the file just below the Project name)
- Select the Target
- Right click and choose Get Info dialog
- Select Build tab
- Fill in the Code Signing Entitlements with Entitlements.plist
Step #4 Verify Target Settings
- Select the Target
- Right click and choose Get Info dialog
- Select Properties tab
- Note the Executable name (e.g. theAstrologerFree)Close the window
- Select Build tab
- Scroll down to Packaging
- Verify (or input) the Product Name to match the Executable name from above
Step #5 Verify Info.plist
- Click on Info.plist in the Resources folder
- Check the following:
- Bundle Display Name - this is the text that will appear on the iPhone Home screen under the icon
- Executable name - this should match what youʼve entered in the Properties settings
- Icon must be set to Icon.png
- Bundle Identifier - for example com.3SixtySoftware.theAstrologerFree
- Bundle version - for example 1.1
Step #6 Clean and Build
- From the Build menu choose Clean All Targets
- From the Build menu choose Build (Command B)
Subscribe to:
Posts (Atom)