Monday, July 27, 2009
Best Practices and your "Personal Brand"
Hanselman's original post is here.
Consciously manage your personal brand.
You work here to help the company, but also yourself. No one will manage your “personal brand” except you. How are you perceived? Do you know? Take negative feedback gracefully, and implement change. Rinse, repeat.
Push the Limits
Chris Sells told me once, If you’re not getting in trouble with your boss at least twice a year, you’re likely not pushing the envelope hard enough. Two slaps a year might be the cost for 10 successes. If you’re not moving forward, well, you’re not moving forward.
Conserve your keystrokes.
When you’re emailing a single person or a reasonably sized cc: list, ask yourself, are you wasting your time? Is this a message that 10 people need to see, or 10,000? Is email where you should be spending your time. Actively be aware of the number of people you communicate with , and the relative level of influence. Is a blog post seen by 50,000 more or less valuable than a single email to your skip-level? Only you can answer, but only if you’re consciously trying to conserve your keystrokes. Your fingers DO have an expiration date; there’s a finite number of keystrokes left, use them wisely.
Don’t give bile a permalink.
While you’re on the clock, think about what you tweet and FB. It only takes one bad link to undo a year’s work. Same goes for tweeting product launches before they’ve launched.
Write down what you’re trying to accomplish and hang it on the wall.
Make T-Shirts. Tell your spouse and kids. If you’re working towards a goal, tell people. It’ll keep you honest and it’ll motivate you. Saying things out loud help make them reality.
Manage Up
Are your commitments aligned with your boss and your bosses boss? Do you have visibility into their commitments? If not, ask for them. Make sure your accomplishments are making yourself, and your boss, look good.
Have a System to Manage Information Flow
If you’ve got 1000 emails in your Inbox, it’s not an Inbox. It’s a pile of crap. Have a system, any system, to triage your work. Any item in your inbox should be processed: Do it, drop it, defer it, delegate it. There are no other actions to take. Are you effectively managing your information flow? Try scheduling time for email on your calendar.
Monday, July 20, 2009
Dudley's Bad Advice
Article:
http://www.examiner.com/x-3040-Life-in-the-Cubicle-Examiner~y2009m7d12-Dear-Dudley-Should-I-quit-my-day-job-after-starting-my-own-business
My response:
Dudley -
I cannot believe the AWFUL advice you actually put in print and published for all the world to see. "Stop caring" and "Try to get laid off"...what is that?!?!?
Where is your personal pride in a job well done? The real character of a person is measured not in what someone does when people are watching, but what a person does when no one is around. You say to "always be incredibly couteous" but you can see this kind of passive aggressive attitude a mile away. This kind of behavior only burns bridges with not only your current company, but the co-workers that are relying on you to do THEIR jobs...which some of them DO enjoy and have pride in.
Remember...we are not only accountable for ourselves! Do a GOOD job and have pride in your work - ALL THE TIME - whether or not it is for someone else or for you. Your name and your reputation are ALWAYS going to follow it.
Wednesday, July 1, 2009
LINQ-SQL – Incorrect results from Count() from Lambda expressions
http://weblogs.asp.net/joelvarty/archive/2009/03/06/linq-sql-incorrect-results-from-count-from-lambda-expressions.aspx
My answer to this issue is below...
I’m surprised Joel didn’t answer his own question of “Can anyone explain this?”…HE is the expert…anyway…I’ll venture my own 2 cents (may be all it’s worth):
The answer is because the Select operator is used to create an output sequence of one kind of element to another type of element. In other words…you have a list of “stuff” and you want to extract another list using the first list as the base. The lambda expression used does not FILTER; rather, it MASSAGES the output data to look the way you want it.
Just as illustration:
You can do the EXACT same thing on the AdventureWorks database. The following uses a quick 5 minute mock up using AdventureWorks and the Entity Framework to access the data:
//ObjectQuery
AdventureWorksEntities entities = new AdventureWorksEntities();
ObjectQuery
int count1 = employees.Count(p => p.Gender == "M");
int count2 = employees.Select(p => p.Gender == "M").Count();
int count3 = employees.Count(p => p.Gender == "F");
int count4 = employees.Where(p => p.Gender == "M").Count();
System.Diagnostics.Debug.WriteLine(string.Format("Males (way 1)(Correct - uses Count): {0}", count1));
System.Diagnostics.Debug.WriteLine(string.Format("Males (way 2)(Incorrect - Uses Select): {0}", count2));
System.Diagnostics.Debug.WriteLine(string.Format("Females (way 1)(Correct - uses Count): {0}", count3));
System.Diagnostics.Debug.WriteLine(string.Format("Males (way 3)(Correct - uses Where): {0}", count4));
Your results will be:
Males (way 1)(Correct - uses Count): 206
Males (way 2)(Incorrect - Uses Select): 290
Females (way 1)(Correct - uses Count): 84
Males (way 3)(Correct - uses Where): 206
The WHERE statement does the similar thing the count does, so you will get the same results.
The proper use of Select would be to get a different view set of employee Data….kind of like the following using anonymous types:
var employeeStuff = employees.Select(p => new
{
AmAWoman = p.Gender == "F",
SSN = p.NationalIDNumber,
UID = p.LoginID,
Title = p.Title,
DOB = p.BirthDate,
Motto = p.Gender == "M" ? "I am a Man!!" : "A am Woman - watch me Roar!"
});
foreach (var item in employeeStuff)
{
System.Diagnostics.Debug.WriteLine(string.Format("{0}; {1}; {2}; {3}; {4}; {5}", item.SSN, item.UID, item.Title,
item.DOB, item.Motto, item.AmAWoman));
}
(results – only the first few)
14417807; adventure-works\guy1; Production Technician - WC60; 5/15/1972 12:00:00 AM; I am a Man!!; False
253022876; adventure-works\kevin0; Marketing Assistant; 6/3/1977 12:00:00 AM; I am a Man!!; False
509647174; adventure-works\roberto0; Engineering Manager; 12/13/1964 12:00:00 AM; I am a Man!!; False
112457891; adventure-works\rob0; Senior Tool Designer; 1/23/1965 12:00:00 AM; I am a Man!!; False
480168528; adventure-works\thierry0; Tool Designer; 8/29/1949 12:00:00 AM; I am a Man!!; False
24756624; adventure-works\david0; Marketing Manager; 4/19/1965 12:00:00 AM; I am a Man!!; False
309738752; adventure-works\jolynn0; Production Supervisor - WC60; 2/16/1946 12:00:00 AM; A am Woman - watch me Roar!; True
690627818; adventure-works\ruth0; Production Technician - WC10; 7/6/1946 12:00:00 AM; A am Woman - watch me Roar!; True
695256908; adventure-works\gail0; Design Engineer; 10/29/1942 12:00:00 AM; A am Woman - watch me Roar!; True
912265825; adventure-works\barry0; Production Technician - WC10; 4/27/1946 12:00:00 AM; I am a Man!!; False
998320692; adventure-works\jossef0; Design Engineer; 4/11/1949 12:00:00 AM; I am a Man!!; False
245797967; adventure-works\terri0; Vice President of Engineering; 9/1/1961 12:00:00 AM; A am Woman - watch me Roar!; True
844973625; adventure-works\sidney0; Production Technician - WC10; 10/1/1946 12:00:00 AM; I am a Man!!; False
233069302; adventure-works\taylor0; Production Supervisor - WC50; 5/3/1946 12:00:00 AM; I am a Man!!; False
Wednesday, June 24, 2009
HierarchyId in SQL Server
Original Email:
I’m a bit worried by posts like this:
http://www.sqlskills.com/blogs/simon/post/SQL-Server-2008-HierarchyId-whats-the-point.aspx
Does anyone know of a strong argument for using HierarchyId?
Microsoft’s documentation on HierarchyId is found here:
http://msdn.microsoft.com/en-us/library/bb677290.aspx
I think conceptually, someone at Micro$oft decided that they wanted a new (data-centric) way of managing information in a hierarchy tree. It sounds like they wanted a one-stop-shop way of being able to parse and determine children and manage nodes that were aware of the current data structure. Just from the last few minutes of research, I cannot say that I’m sold on it seeing as I come from an “old school” of managing these types of relationships – good old fashion data structures and a good data model that logically describes what you are trying to convey. Adding an additional ID (and management layer) which lays the management responsibility on the database, in my opinion, reduces your flexibility and ability to manage the data as you need. What’s the old saying: some are willing to give up freedom for security/convenience – sounds like other things happening on a national level – ah, but I digress! (Enough on that)
Monday, June 15, 2009
Complexity in UML Modeling
The Question:
Top 10 concepts/ things designer/ modeler finds it difficult to model using UML 1.x/ 2.x standards. This doesn't includes complexity/ easiness of using specific tools. Eg. modeler may find it difficult to model concurrency/ scheduling/ priority/ activites in a loop etc.
My Answer:
Well, I don't have 10, but I can give you the biggest drawback (as I will call it) regarding UML modeling in general. Contrary to many-an-architect's efforts, software has always been fluid. Changing requirements and design have been with us since the dawn of the first computer program. We have evolved a great deal with the processes that we use to create software - from Waterfall to agile - we have always had to find new and better ways to handle changes.
UML is a wonderful tool in conveying the intent, design, and operation of the software we are architecting. The drawback with it is the same as the software we are writing - how to handle changes. A UML diagram is good only for the moment that it is drawn. Once the design or code has been refactored, the diagram is useless.
Do we stop using UML?? By no means - I think we need to use it for what it is best at - conveying architecture and design while the software is being built. OK...what do I mean by that? Here are some concrete examples:
Use cases - with the intent of documenting the requirements - we should expect it to be fluid over time. Can (and should) change - make sure that your tool can baseline your requirements and gives you the ability to document them over time.
Class, object, state diagrams - useful for showing the current relationships of the objects being used - likewise can be used during a code/design session to help convey ideas. Shouldn't put one of these into a design document because it WILL change upon the refactoring of the system. Best used as a tool during the design and code phase for collaboration between developers or helping a developer/architect to "visualize" the object relationships. If the development IDE can generate these - then all the better - don't spend your time trying to manually keep up with these.
Sequence, collaboration, activity - shows the actions going on between the objects over time. Once again - only accurate for the moment it is printed. I have used many of these on a white board explaining the operation of a process or system, and have published a few of them too. Once again - if your IDE can generate one, then great. Don't spend your time manually keeping up with them - you'll be chasing your tail.
Component and deployment diagrams - don't change as quickly and can convey the overall architecture. I would say these are easier to keep up with manually because of the nature of the information they are conveying.
Overall - my favorite use of UML diagrams are (as mentioned above):
- On a white board to convey an idea and/or architecture. Good for getting the ideas across, using them for the design or code and then throwing them away.
- If you have an IDE or tool that can auto generate UML diagrams for you, then I've used them to auto-generate models so I could understand new code as I am coming up to speed with an existing application.
Anyway...that is my 2-3 cents worth. I'd be interested in hearing what others have to say.
Wednesday, May 27, 2009
Database Inheritance - my 2 cents
I'm currently in a discussion with a co-worker regarding how to implement inheritance in a database. Yes...I know that databases don't directly support inheritance, but there are some common patterns to how this can be handled.
Martin Fowler talks about the three major database inheritance patterns…
Single Table: http://www.martinfowler.com/eaaCatalog/singleTableInheritance.html
Class Table: http://www.martinfowler.com/eaaCatalog/classTableInheritance.html
Concrete Table: http://www.martinfowler.com/eaaCatalog/concreteTableInheritance.html
The way we have it implemented now is using the concrete table method. I have to admit I am more of an advocate of the class level method. I know the CRUD methods are a bit more complex, but I believe it pays some better dividends in the realm of maintenance as well as the model being more straight forward. The two main maintenance items I’m talking about are that if any of the common fields change, then you have multiple tables to modify as well as the DAO and DTO objects to update. The biggest item, however, is enforcing database relationships. We have other tables that reference back to the main identifier – if they are separated into different tables, then there is no way to enforce that relationship. It will also make the logic behind those interactions more complex as well - not to mention the queries to support the reports that will need to be generated from the data.
Anyone else have any other comments - I'd love to hear them!
Dependency Properties - "Pre"-compilation
I'm not sure where to turn - other than just refactoring the way I'm doing things so I don't have to use the technique/design that I've put together. Which is what I'm going to do after I post this.
Here is the scoop:
I'm putting together a rather large state machine workflow using Windows Workflow Foundation. I have a custom activity that I've built that takes in an object and does some "stuff" based on the object that is passed in. Specifically, the activity calls an object that sends some notifications - this code was already written and we are just reusing it. The Custom activity simply is the wrapper to do the notifications. OK...easy enough...
To call this activity from my workflow - I need a reference to the object that has the information regarding the people to notify. In my example I have a Quote object. This quote object has some information that tells the notification which people need notified. (note that the notification object takes different types and can notify based on those different types...the Quote is simple a concrete version of those other types).
So, how do I do this - I create a dependency property in by custom activity called EntityForNotification. The type of that dependency Property is of the parent type for Quote - so I can send a Quote or other concretes into it. Then it will take and perform notifications. In my State Machine workflow, I add the custom activity and set the dependency property to a dependency property that I have set up in my state machine. In this case - the Dependency Property is called "Quote".
Here is the code for the dependency property in the state machine which needs to pass the Quote to the custom activity:
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)][BrowsableAttribute(true)]
[CategoryAttribute("Notify Task")]
public QuoteDto Quote
{
get { return (QuoteDto)GetValue(QuoteProperty); }
set { SetValue(QuoteProperty, value); }
}
// Using a DependencyProperty as the backing store for Quote. This enables animation, styling, binding, etc...
public static readonly DependencyProperty QuoteProperty = DependencyProperty.Register("Quote", typeof(QuoteDto), typeof(QuoteStates), new PropertyMetadata(null, DependencyPropertyOptions.Default, new GetValueOverride(getQuoteValueOverride), new SetValueOverride(setQuoteValueOverride)));
private object getQuoteValueOverride(DependencyObject dependencyObject)
{
QuoteDto result = null;
// Get the quote ID
Guid quoteID = ((QuoteStates)dependencyObject).QuoteID;
// Now return the quote Dto
QuoteDao quoteService = new QuoteDao();
result = quoteService.SelectByPrimaryKey(quoteID);
return result;
}
private static void setQuoteValueOverride(DependencyObject dependencyObject, object value)
{
// Not used.
}
Notice my usage of the PropertyMetaData and the delegates that override the get and set methods. I don't want to mess with the default getter and setter for the dependency properties, so (as directed by the MSDN forums) I put my custom creation of the QuoteDto into my overridden Quote getter.
The problem is, that it won't compile. I get a very long winded stack trace (pasted at the bottom of this post) that tells me that my configuration file doesn't contain the connection string for the database connection that is being used by my QuoteDao service - which, by the way, is in a completely different assembly - and works wonderfully in getting my QuoteDto objects. I can comment out the line of code that calls the .SelectByPrimaryKey(quoteID) and it compiles and runs fine. The problem is - with that commented out, there is no quote Dto that gets created and sent back - so that defeats the purpose.
Why in heaven's name is it trying to validate the Workflow activity based on a call to a completely different assembly and it's need to see a configuration file. Shouldn't they be completely decoupled??? The workflow foundation has injected a dependency that I neither asked for or even want/need - ie. I don't want to create another configuration file to make sure my workflow works. The configuration file is already in my project in another place and enables my data layer to work just fine in all of the other places in my code.
I think that is about it...if anyone has any suggestions, I'm very willing to hear them.
Thanks!!
Below is the stack trace for my error:
--------------------------------------------------------------------------
Error 1 'System.Configuration.ConfigurationErrorsException' while invoking the validator 'System.Workflow.Activities.StateActivityValidator' on activity 'QuoteStates': System.Configuration.ConfigurationErrorsException: The requested database ODS is not defined in configuration. at Microsoft.Practices.EnterpriseLibrary.Data.DatabaseConfigurationView.ValidateConnectionStringSettings(String name, ConnectionStringSettings connectionStringSettings) at Microsoft.Practices.EnterpriseLibrary.Data.DatabaseConfigurationView.GetConnectionStringSettings(String name) at Microsoft.Practices.EnterpriseLibrary.Data.DatabaseCustomFactory.CreateObject(IBuilderContext context, String name, IConfigurationSource configurationSource, ConfigurationReflectionCache reflectionCache) at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.ConfiguredObjectStrategy.BuildUp(IBuilderContext context, Type t, Object existing, String id) at Microsoft.Practices.ObjectBuilder.SingletonStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild) at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild) at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.ConfigurationNameMappingStrategy.BuildUp(IBuilderContext context, Type t, Object existing, String id) at Microsoft.Practices.ObjectBuilder.BuilderBase`1.DoBuildUp(IReadWriteLocator locator, Type typeToBuild, String idToBuild, Object existing, PolicyList[] transientPolicies) at Microsoft.Practices.ObjectBuilder.BuilderBase`1.BuildUp(IReadWriteLocator locator, Type typeToBuild, String idToBuild, Object existing, PolicyList[] transientPolicies) at Microsoft.Practices.ObjectBuilder.BuilderBase`1.BuildUp[TTypeToBuild](IReadWriteLocator locator, String idToBuild, Object existing, PolicyList[] transientPolicies) at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.EnterpriseLibraryFactory.BuildUp[T](IReadWriteLocator locator, String id, IConfigurationSource configurationSource) at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.EnterpriseLibraryFactory.BuildUp[T](String id, IConfigurationSource configurationSource) at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.NameTypeFactoryBase`1.Create(String name) at Microsoft.Practices.EnterpriseLibrary.Data.DatabaseFactory.CreateDatabase(String name) at GeneraliUsa.Everest.DataAccess.Base.DaoBase.get_Database() in C:\Projects\Everest\Source\App\Libraries\GeneraliUsa.Everest.DataAccess\Base\DaoBase.cs:line 145 at GeneraliUsa.Everest.DataAccess.SalesQuote.QuoteDaoBase.SelectByPrimaryKey(Guid quoteId) in C:\Projects\Everest\Source\App\Libraries\GeneraliUsa.Everest.DataAccess\SalesQuote\QuoteDaoBase.cs:line 170 at GeneraliUsa.Everest.Workflow.Workflows.Quote.QuoteStates.getQuoteValueOverride(DependencyObject dependencyObject) at System.Workflow.ComponentModel.DependencyObject.GetValue(DependencyProperty dependencyProperty) at System.Workflow.ComponentModel.Compiler.DependencyObjectValidator.ValidateDependencyProperty(DependencyObject dependencyObject, DependencyProperty dependencyProperty, ValidationManager manager) at System.Workflow.ComponentModel.Compiler.DependencyObjectValidator.Validate(ValidationManager manager, Object obj) at System.Workflow.ComponentModel.Compiler.ActivityValidator.Validate(ValidationManager manager, Object obj) at System.Workflow.ComponentModel.Compiler.CompositeActivityValidator.Validate(ValidationManager manager, Object obj) at System.Workflow.Activities.StateActivityValidator.Validate(ValidationManager manager, Object obj) at System.Workflow.ComponentModel.Compiler.XomlCompilerHelper.ValidateActivity(Activity activity, WorkflowCompilerParameters parameters, WorkflowCompilerResults results) C:\Projects\Everest\Source\App\Libraries\Generali.Everest.Workflow.BusinessProcesses 1 1