.NET 2.0 GridView for winforms... why is it so slow?
Is it just me, or is the .NET 2.0 gridview control for Winforms about the slowest grid-like control that has ever been released? I mean, the painting of it is so incredibly slow, it hurts the eye.
In SqlServer 2005's management studio, open a table in Object explorer so you get a grid of rows. Open a table which has enough rows for a full screen. Then open a query window, which is effectively a new tab. Switch between the two by just clicking the tab headers. On my Xeon 3GHz box I see the painting done top to bottom on the grid which is taking at least half a second.
I noticed the same thing in a simple .NET 2.0 app with a Gridview on it. Other people have the same thing?
Placement of Solution Explorer in VS.NET
The first time I ran VS.NET 2005, I was asked to select a profile matching my developing needs. I selected the C# developer profile and expected to have the Solution Explorer docked to the left side of the IDE. Though, it was placed on the right side. This is IMHO a bad choice.
I think it should be docked on the left side because of the following:
A developer who looks in rest-position at the monitor normally looks at the center of the screen (funny jokes aside what you define as 'rest' position ). Because all code is left-aligned (unless you're using hebrew or arabic writing), the left half of the code window has more code statements than the right-half of the code window. Having the Solution Explorer docked at the left (and the Solution Explorer is likely to be opened at all times) the left side of the code window is placed at or around the point where the developer will look at in rest-position. If you have the Solution Explorer at the right side of the IDE, the left half of the code window, with most of your code, is positioned at the left side of the IDE, and thus at the left side of your screen. You then thus have to look at the left side of your screen to see your main focus of work, IMHO that's not the most optimal position.
SqlServer 2005's installer... Oracle Quality, at last!
SqlServer 2005's installer is a bit hopeless. It needs IE to get you started. Not a problem. I open the page in IE 6 on XP, I give it permission to run objects/activex and what have you. Then I click a link. "Error on page", IE says.
So hunting through the sourcecode I find a link, to an .hta page. Also doesn't work. So I hunt through that sourcecode as well and find a setup.exe. Unfortunately for me, it was in the Tools folder. I run it, but at the end, of course, no SqlServer 2005 installation. Just docs 'n tools. Though the installer gives you the suggestion everything is installed. It even displays the dialog where it explains you have to run the config wizard to start services.
Why on earth isn't there a single installer, which simply starts with a .exe, like in SqlServer 2000? It's great Sqlserver finally got a lot of Oracle's features, but one 'feature' wasn't that required to be implemented in SqlServer: Oracle's horrible installer.
Ok, take 14...
(Update): Ok, the setup.exe in the Servers folder is the real setup. So don't bother with the setup in the Tools folder nor with the .htm files or .hta files. Also, if you're installing on a system where SqlServer 2000 is already installed, be sure to select during the setup of SqlServer 2005 for a named instance and give it a logical name, like SqlServer2005 (don't include spaces). This way you can refer to the SqlServer instance as yoursystemname\SqlServer2005 in the connection string for connections to SqlServer 2005 and yoursystemname in the connection string for connections to SqlServer 2000.
Another tip: after installation of SqlServer 2005 and/or VS.NET 2005, you'll probably notice a new service which eats a lot of CPU time. This is the NGEN service, which is NGEN-ing the .NET assemblies and sqlserver .net code. So be patient (takes a couple of minutes)
VS.NET 2005/Sqlserver 2005 RTM and are available at MSDN
Now, the MSDN subscriber download site seems to be hammered by a gazillion mad geeks looking for the bits as it seems, because downloading seems impossible at the moment, but I'm sure it will ease somewhat in the coming hours (yes that was wishfull thinking )
Congrats to the VS.NET and Sqlserver teams with this big milestone!
LLBLGen Pro v1.0.2005.1 released!
Time flies when you're having fun, they say, and it's true . After 6 months of hard work, it's finally done: LLBLGen Pro v1.0.2005.1 is available. This release is a significant milestone, because it includes some key elements, like full inheritance and for example basic support for .NET 2.0.
Let's have a look at some of the new key features:
- Full inheritance support. LLBLGen Pro now supports 3 types of entity inheritance:
- Complete hierarchy mapped onto a single table. In LLBLGen Pro this is called TargetPerEntityHierarchy. This is the inheritance type which is very easy to implement and therefore supported by most O/R mappers.
- Every type in a hierarchy mapped onto its own table, no discriminator column. In LLBLGen Pro this is called TargetPerEntity. This inheritance type is hard to implement, most O/R mappers fall back to option 3.
- Every type in a hierarchy mapped onto its own table, with discriminator column in root type. Similar to option 2, and because LLBLGen Pro doesn't need a discriminator column for option 2, this type is supported but the discriminator column is ignored / not required.
- Compact Framework support, including support for SqlServer CE
- Type conversion technology, map transparently any .NET type on any database type Type converters let you map an entity field of any type onto any database field. LLBLGen Pro will do the conversion transparently for you, behind the scenes. You just work with the entity field type. With this you can for example map a boolean entity field onto a NUMBER(1,0) in Oracle, to have true database generic code, which works with SqlServer and Oracle (SqlServer supports a bit/boolean type, Oracle doesn't). But it doesn't stop there, you can also use this to map a field with type XmlDocument onto a varchar database field. The conversion is done through simple TypeConverter objects which are easy to create yourself and which are used inside the LLBLGen Pro designer to control the types of fields which have a type converter applied.
- New, easy to use, compile-time checked query construction mechanism. Here's an example:
Get all orders which have been shipped 4 days after the orderdate:
// C#, SelfServicing OrderCollection orders = new OrderCollection(); orders.GetMulti(OrderFields.ShippedDate == (OrderFields.OrderDate + 4));
// C#, Adapter EntityCollection orders = new EntityCollection(new OrderEntityFactory()); adapter.FetchEntityCollection(orders, new RelationPredicateBucket(OrderFields.ShippedDate == (OrderFields.OrderDate + 4)));
' VB.NET 2005. SelfServicing Dim orders As New OrderCollection() orders.GetMulti(OrderFields.ShippedDate = (OrderFields.OrderDate + 4))
' VB.NET 2005, Adapter Dim orders As New EntityCollection(New OrderEntityFactory()) adapter.FetchEntityCollection(orders, _ new RelationPredicateBucket(OrderFields.ShippedDate = (OrderFields.OrderDate + 4)))All compile time checked and easy to formulate.
- Map as many entities onto a single table/view
- Polymorphic queries and polymorphic prefetch paths
Say you have an inheritance hierarchy of entities: Employee <- Manager <- BoardMember, and BoardMember has a relation with CompanyCar (m:1) which also is an inheritance hierarchy: CompanyCar <- SportsCar and CompanyCar <- FamilyCar.
Fetching all Employees in a collection, will fetch all Manager entities into objects of type ManagerEntity and all BoardMember entities into objects of type BoardMember. Say you want to load all employees and also for each boardmember the company car they have, and as efficient as possible. This asks for a prefetch path, which allows you to specify which related objects to fetch together with a set of fetched objects. Our code then looks like:
// C#, Adapter PrefetchPath2 path = new PrefetchPath2((int)EntityType.EmployeeEntity); path.Add(BoardMemberEntity.PrefetchPathCompanyCar); EntityCollection employees = new EntityCollection(new EmployeeEntityFactory()); adapter.FetchEntityCollection(employees, null, path);
' VB.NET, Adapter Dim path As New PrefetchPath2(CInt(EntityType.EmployeeEntity)) path.Add(BoardMemberEntity.PrefetchPathCompanyCar) Dim employees As New EntityCollection(new EmployeeEntityFactory()) adapter.FetchEntityCollection(employees, Nothing, path)This not only fetches all employee types in objects of the right types, but also fetches only for the boardmember entities the related company car entity, and because CompanyCar is also a hierarchy, each loaded company car will be loaded into objects of the right type: FamilyCar or SportsCar.
- Support for SqlServer 2005 (no UDT's/UDF's/CTE's) Support for the database types varchar(MAX), varbinary(MAX) and Xml is added as well as creating projects based on SqlServer 2005 catalogs and generating SQL at runtime fully compatible with SqlServer 2005. No support for UserDefinedTypes and UserDefinedFunctions based on CLR types nor support for CTE's. This will be added to LLBLGen Pro v2.0.
- Support for partial classes in .NET 2.0, design time databinding and native .NET 2.0 runtime libraries.
- Much faster/compact serialization for remoting.
This upgrade is, as always, free for our customers. If you want to download the demo, please go to this download mirror, to avoid hammering our server: Solutions Design website (12 MB)
Full list of changes
- All type enums are now public
- Firebird driver is now build against v1.7a of the Firebird.NET provider
- Sqlserver's driver now always reads the @@IDENTITY sequence as well, so users can set entity field sequences to @@IDENTITY instead of SCOPE_IDENTITY() if they want to. This is required for entities mapped onto views and which are used with instead-of triggers. The driver now also signals calling code that the user can select a sequence, so in the designer a user can now select a sequence for a field in an entity, this isn't disabled anymore for projects targeting SqlServer.
- SqlServer driver: support for Xml types in SqlServer 2005
- Oracle drivers using ODP.NET: support for XMLType types in Oracle 9i/10g
- Adapter: Catalog name overwriting at runtime has been reworked. You can now pass in a CatalogNameOverwriteHashtable which contains all the name value pairs and the setting what to use. Internally the DataAccessAdapter uses this setting as well. Name overwriting is now done by the DQE at fieldname construction, not when the fieldpersistenceinfos are retrieved. Wildcard can be used. SQLServer specific
- Structure of DQE's: they're now instance classes, no longer classes with static methods.
- Reworked recursive save pipeline using topology sorting of a directed graph: first queues are constructed, then the save actions are started on these queues. This both gives faster recursive saves, but also keeps the transaction shorter (in time), as it's started later (selfservicing has same starts, adapter starts the transaction later). Originally, the recursive save routine saved the entities while traversing/building the tree.
- UnitOfWork classes now use the new recursive save pipeline elements to construct first queues to process before starting the actions on these queues. When a unitofwork(2) object is serialized, it first determines the real elements to save, which makes serializing unitofwork(2) objects very efficient, as only the elements which will take part of a persistence action are serialized into the UnitOfWork(2) serialized data.
- Adapter: serialization / deserialization of entities is now much faster and the data produced is up to 60% smaller.
- Selfservicing: Multi-entity fetch logic now calls OnFetchComplete() after an entity was succesfully fetched and filled with data. Post-fetch initialization logic should be placed inside a method which overrides OnFetchComplete().
- Inheritance support (3 types of inheritance)
- Multi entity on single target mapping
- Type converter technology for converting values transparently from one .NET type to the other .NET type and vice versa, to be used in Entity/View fields and predicates. For example, it offers the ability to map boolean fields directly on non-boolean/bit types in the database, or for example to map an XmlDocument object onto a string type.
- Ability to not map a field in a table / view to a field in an entity
- Polymorphic query support including filtering on entity type
- Compact framework .NET 1.1 support
- SQL CE support
- Prefetch path fetches in combination with paging
- Adapter: Schema name overwriting settings at runtime for multiple schema name overwrites. You can pass in a SchemaNameOverwriteHashtable which contains the from-to namepairs and the setting what to do. Wildcard can be used. SQLServer, Oracle, DB2 specific.
- MySql: Update entities directly with multi-entity filter has been added.
- FieldBetweenPredicate now also handles field BETWEEN value AND field, field BETWEEN field AND value, field BETWEEN field AND field
- ORMInheritanceInfoException exception, meant for errors determined during query execution, for example when the inheritance info data is out of sync with the data in the db, which occurs for example when the type has to be determined of the row retrieved from the db and the discriminatorvalue is unknown.
- Prefetch path optimization with a user definable threshold when to switch from one method to the other.
- Support for Cross joins.
- Overload to DataAccessAdapter.SaveEntity, which accepts recurse and refetchAfterSave but not a predicate.
- SelfServicing: EntityCollectionBase.DoNotPerformAddIfPresent flag to signal if EntityCollectionBase.Add() should check if the entity to add is already in the collection (default, true) or not (false).
- Adapter: New overloads for FetchTypedList and FetchTypedView which are simpler to use (e.g. accept a typedlist/typed view and don't require you to retrieve the fields info / relations info first.
- EntityCollectionBase(2) now has 2 properties (ConcurrencyPredicateFactoryToUse and EntityValidatorToUse) which will set these properties of any new entity created in a collection fetch to the values stored in these two properties. Also done when AddNew() is called in a databinding scenario.
- OnBeginEdit(), OnEndEdit(), OnCancelEdit(), OnTransactionCommit() and OnTransactionRollback() as protected virtual methods to EntityBase(2).
- Adapter specific constructor to EntityRelation class.
- SqlServer: inserts into a table with solely an identity field are now possible. (INSERT INTO table DEFAULT VALUES)
- Prefetch path optimization through caching of PK hashes.
- UnitOfWork(2) now offer a way to construct the insert/update queues prior to actually committing them. These queues aren't reset after a commit so can be used to fine-grained control over the elements participating in the unitofwork.
- Native .NET 2.0 builds for the ormsupport classes and various DQE's. The ORM support classes build doesn't use ICustomTypeDescriptor on the entity classes, which should enable design time databinding on .NET 2.0 for the time being. (winforms).
- Polymorphic prefetch paths: fetches of supertypes can be performed with prefetch paths which refer to related objects of subtypes and which will load only the subtype's related objects into the subtype instances (if available).
- SortClause.CaseSensitiveCollation. This flag will apply UPPER() (or db specific equivalent) to the field to sort on, to make case sensitive database installations be able to sort case insensitively.
- Adapter: OnBeforeTransactionCommit, OnAfterTransactionCommit, OnBeforeTransactionRollback and OnAfterTransactionRollback added to DataAccessAdapterBase as public virtual methods.
- Adapter: New constructor to RelationPredicateBucket which accepts an IPredicate to ease the construction of filters for Adapter.
- The regular color in the logviewer is now green instead of maroon. Errors are now much easier to spot.
- Custom entity relation editor: the checkbox for auto-detect m:n relations is now only checked if the refresher preference to hide m:n relations automatically is set to false.
- Custom entity relation editor: the name of the field mapped onto the relation to create is now initially set with the name of the related entity.
- Relation nodes of an entity are now sorted ascending in project explorer
- Fields mapped onto relation nodes of an entity are now sorted ascending in project explorer.
- It's now possible to select a sequence for a field which is in an entity mapped onto a view and mark it as identity for sqlserver.
- New preference setting: AddNewFieldsAfterRefresh, which controls if newly found target fields are added as new fields or are added to the list of unmapped fields.
- New preference setting: HideManyToManyRelationsOnCreation, which controls if newly created m:n relations should be marked 'hidden' by default.
- Multiple entities can now be mapped on a single target.
- Entity list viewer for proper overview which entity is mapped onto which target.
- New preference setting: AutoAssignTypeConverterToNewField, which controls if a newly added field (for example in a new entity) gets a matching type converter assigned to it automatically, based on the type conversion definitions defined in the project.
- Plugin which toggles the hide flag on m:n relations. If a relation can't be made unhidden (because one of the two relations it's build on is hidden), it's not marked unhidden.
- Plugin which applies selected Type Conversion Definitions to selected elements, to quickly set type converters on existing projects.
- Option (ManuallySelectRenamedTargetsAfterRefresh) added which will cause the refresher to pop up a dialog (if not unattended) in which the user can select which target to select for a given entity, if the target couldn't be found by the refresher, for example in the case when the target has been renamed.
- Option (LazyLoadingWithoutResultReturnsNew) added to set the flags for the _entityReturnsNewIfNotFound flags in Selfservicing to a value specified in the designer. This makes it easy to set this flag once for all generated entities. Selfservicing specific.
- Context menu to Relations treeview in Entity Editor for easy removal of custom relations and toggle actions on relations.
- Typed list relations can now also have the join hint for a Cross join.
- Typed list designer now has 'Field index' in the column list of the fields in the select list. Use shift-click on the column headers to sort on multiple columns.
- Entities mapped onto views can now have nullable fields.
- Entity hierarchy visualizer.
- Lpt templates can now be bound to templateid's which are included in TDL templates. This greatly enhances the scope of the include templates as with lpt templates (with <% %> syntax and template code in C#/VB.NET) it's possible to access the complete project object graph. This is completely transparent, just bind a .lpt template to a template id which is included in a TDL template and it will be called.
- Two new overloads to ResultsetFields.DefineField() for each typed view, which accept an alias for the field.
- New method in entity classes: TestCurrentFieldValueForNull(index), which returns true if the current value of a field represents null/undefined. This is for example the case for a field of a new entity which hasn't been changed, or a field in a non new entity which hasn't been changed or which has been set to null/Nothing.
- Support for partial classes in VS.NET 2005 scenario's: all classes are generated as partial classes (C#) if a VS.NET 2005 generator scenario is chosen. VB.NET 2005 classes can already be extended with partial classes without having the generated classes defined as 'Partial'.
- Full inheritance support. LLBLGen Pro now supports 3 types of entity inheritance:
Server problems solved
We're experiencing server problems at the moment at llblgen.com, our ISP is looking into the problem now, hopefully it's solved a.s.a.p. Problems were solved, but it's failing again. . Due to heavy traffic for our new version, the server burned down. We hope to solve it a.s.a.p.
Pro ADO.NET 2.0 by Sahil Malik, a review
My good friend Sahil Malik recently released his second book, called Pro ADO.NET 2.0. The book is about .NET's API to work with databases: ADO.NET, and especially its newest incarnation: ADO.NET 2.0 for .NET 2.0.
Back from the Summit
Summit was awesome! I think that word covers it. Had a great time, met a lot of great people and it was well worth it. Mr. Jetlag payed me a visit however with his little brother Johnny Cold so I'm not feeling very well, physically, at this moment, but that will be gone in a few days, I'm sure . Can't say anything about the content (NDA), other than about stuff that's already in the open, like DLinq. I wrote during the DLinq demo the same code in LLBLGen Pro 1.0.2005.1 (which is currently in beta), with even fewer lines of code. . WITH compile time checking of filters etc. It's gonna be a great authumn.