[Reflection.Assembly]::LoadFile("C:\temp\Microsoft.SharePoint.dll")
foreach ($value in [Microsoft.SharePoint.SPFieldType]::GetValues
([Microsoft.SharePoint.SPFieldType]))
{
$int = [Convert]::ToInt32($value)
Write-Host $value = $int
}
Wednesday, August 17, 2011
Powershell script to list the integer value of each member of an Enumeration
I couldn't easily find something that did this, so here is what I came up with.
Wednesday, August 3, 2011
Using PowerShell to do a find and replace on all files and subfolders
I looked around for a while and just couldn't find a script that did this for me. So here it is so I don't lose it. It was useful as part of setting up a new VS2010 project that was a complete copy of the one from another project.
$search = "SearchString"
$replace = "ReplaceString"
function RenameFile ($fileInfo)
{
if ($fileInfo.Name.Contains($search))
{
$newFullName = $fileInfo.DirectoryName + "\" + $fileInfo.Name.Replace($search, $replace)
Move-Item $fileInfo.FullName $newFullName
return 1
}
return 0
}
function RenameDirectory ($dirInfo)
{
if ($dirInfo.Name.Contains($search))
{
$newFullName = $dirInfo.Parent.FullName + "\" + $dirInfo.Name.Replace($search, $replace)
Move-Item $dirInfo.FullName $newFullName
return 1
}
return 0
}
$files = Get-ChildItem -Path . * -Recurse -Force
$i = 0
$j = 0
# Rename files
foreach ($file in $files)
{
if ($file.GetType().ToString() -eq "System.IO.FileInfo")
{
if (RenameFile($file) -eq 1)
{
$i = $i + 1
}
}
}
# Now rename directories
foreach ($file in $files)
{
if ($file.GetType().ToString() -eq "System.IO.DirectoryInfo")
{
if (RenameDirectory($file) -eq 1)
{
$j = $j + 1
}
}
}
Write-Host Renamed $i files, $j directories.
Tuesday, August 2, 2011
Musings on using Unity Interception to achieve automatic INotifyPropertyChanged
I was just about to look at using Unity to implement automatic INotifyPropertyChanged. I've been meaning to do it ever since I heard the latest version of Unity for Silverlight supported method interception. It has just dawned on me however, that I might want to look again for a better option because (and I could be wrong) but using method interception will cause me one nasty little problem.
So, Unity will do a good job with something like this:
But what about this code?
What am I going on about here? In a nutshell, the change notification won't happen when setting property values from within the object itself, since internally it isn't going through Unity.
I've only thought about it for a few minutes... But I think the workaround for this won't be terribly nice... and I've just seen a posting about this project, so I think I'll go check it out first.
So, Unity will do a good job with something like this:
var x = container.Resolve<IMyInterface>();
x.PropertyOne = "This will work";
But what about this code?
public void SomeMethod()
{
this.PropertyOne = "I don't think this will work";
}
What am I going on about here? In a nutshell, the change notification won't happen when setting property values from within the object itself, since internally it isn't going through Unity.
I've only thought about it for a few minutes... But I think the workaround for this won't be terribly nice... and I've just seen a posting about this project, so I think I'll go check it out first.
Tuesday, July 19, 2011
Using RIA Services Contrib's EntityGraph to easily do partial saves to entities
UPDATE (29 Nov 2011): The RIA Services contrib project now has built in support for this functionality, see here.
I love RIA Services. Using it for our latest project saved us a stack of time, however... An area I found particularly painful was doing partial saves, particularly when you may have a group of related entites that you wish to save, without having to do a full save via RIA's SubmitChanges() method. The problem with SubmitChanges() is that it saves everything, which often is not what you want.
The system we have just finished and released to production makes extensive use of RIA Services and Prism. It allows the user to have multiple edits all happening at once on the one tree of hierarchical information, with a rich UI that updates all open windows instantly when edits occur. It also has full support for concurrent users all working on the one tree of records at the same time.
Thanks to the post here, the SubmitPartialChanges method allowed us to initially do saves of single modified Entites without inadvertenly saving all other modified entities the user had open. However, as the project continued, the need arose for not only a single Entity to be saved, but related modified Entities too, all in the one save operation.
To cut a long story short, at the time, it took a lot of code to make doing this perform well, and be transactional. Making multiple calls to SubmitPartialChanges() (one for each modified Entity) is slow, puts a lot of load on the server, and is not transactional. Writing the code to do it yourself is time consuming and difficult to read. Towards the end of the project, I found the recent work done in RIA Services Contrib on Codeplex that introduces the concept of the Entity Graph.
Take a moment to check out what it does. It was too late for us (it is still in Beta at the time of this writing, and didn't exist at the beginning of our project). Recently I've taken a look at using EntityGraph to allow for easily saving the Entities in the graph.
Below is a code snippet that uses some new extension methods to easily perform partial saves. The code is quite concise, and much better than what it would have looked like otherwise. The two extension methods of note are CloneEntityGraphAndAttach() and ApplyEntityGraphState().
And below are the extension methods used.
I love RIA Services. Using it for our latest project saved us a stack of time, however... An area I found particularly painful was doing partial saves, particularly when you may have a group of related entites that you wish to save, without having to do a full save via RIA's SubmitChanges() method. The problem with SubmitChanges() is that it saves everything, which often is not what you want.
The system we have just finished and released to production makes extensive use of RIA Services and Prism. It allows the user to have multiple edits all happening at once on the one tree of hierarchical information, with a rich UI that updates all open windows instantly when edits occur. It also has full support for concurrent users all working on the one tree of records at the same time.
Thanks to the post here, the SubmitPartialChanges method allowed us to initially do saves of single modified Entites without inadvertenly saving all other modified entities the user had open. However, as the project continued, the need arose for not only a single Entity to be saved, but related modified Entities too, all in the one save operation.
To cut a long story short, at the time, it took a lot of code to make doing this perform well, and be transactional. Making multiple calls to SubmitPartialChanges() (one for each modified Entity) is slow, puts a lot of load on the server, and is not transactional. Writing the code to do it yourself is time consuming and difficult to read. Towards the end of the project, I found the recent work done in RIA Services Contrib on Codeplex that introduces the concept of the Entity Graph.
Take a moment to check out what it does. It was too late for us (it is still in Beta at the time of this writing, and didn't exist at the beginning of our project). Recently I've taken a look at using EntityGraph to allow for easily saving the Entities in the graph.
Below is a code snippet that uses some new extension methods to easily perform partial saves. The code is quite concise, and much better than what it would have looked like otherwise. The two extension methods of note are CloneEntityGraphAndAttach() and ApplyEntityGraphState().
...
EntityGraph graph = MechanicModel.EntityGraph(tbl_Mechanic.RepairJobPartShape);
if (MechanicModel.EntityState == EntityState.New ||
MechanicModel.EntityState == EntityState.Detached)
{
addingNewMechanic = true;
// Add the new Mechanic to the temporary domain context
tempDomainContext.tbl_Mechanics.Add(MechanicModel);
// Create the repairJob-mechanic link
repairJobMechanicLink = new tbl_RepairJob_Mechanic();
repairJobMechanicLink.RepairJobId = repairJob.Id;
repairJobMechanicLink.tbl_Mechanic = MechanicModel;
tempDomainContext.tbl_RepairJob_Mechanics.Add(repairJobMechanicLink);
// Create the links to each part of the repairJob
foreach (tbl_Part part in repairJob.tbl_Part)
{
tbl_Part_Mechanic_RepairJob partLink =
new tbl_Part_Mechanic_RepairJob();
partLink.PartId = part.Id;
partLink.tbl_RepairJob_Mechanic = repairJobMechanicLink;
tempDomainContext.tbl_Part_Mechanic_RepairJobs.Add(partLink);
}
}
else
{
// Clone the object graph into the temporary context
tempDomainContext.CloneEntityGraphAndAttach(graph);
}
// Update the temporary context with the server
tempDomainContext.SubmitChanges(
submitOperation =>
{
if (submitOperation.HasError)
{
...
}
else
{
if (addingNewMechanic)
{
// Clone and then attach the new mechanic's object graph to the
// real domain context
DomainContext.tbl_Mechanics.Attach(graph.Clone());
}
else
{
// Apply the saved state back to the real entities...
DomainContext.ApplyEntityGraphState
(tempDomainContext.tbl_Mechanics.First().EntityGraph
(tbl_Mechanic.RepairJobPartShape));
}
...
}
}
...
And below are the extension methods used.
using System.ServiceModel.DomainServices.Client;
using System.Collections;
using System.Reflection;
using System;
using System.ComponentModel.DataAnnotations;
using RiaServicesContrib.DomainServices.Client;
using RiaServicesContrib.Extensions;
namespace Infrastructure
{
public static partial class DomainContextExtensions
{
/// <summary>
/// Applies the state of each Entity in the graph to the
/// clones in this DomainContext.
/// </summary>
/// <param name="graph"></param>
/// <param name="contextToApplyState"></param>
/// <remarks>This only currently works for Entities with an
/// integer Key value</remarks>
public static void ApplyEntityGraphState
(
this DomainContext contextToApplyState,
EntityGraph graph
)
{
foreach (Entity entity in graph)
{
// Apply the state of the cloned entity to the real one....
ApplyStateToMatchingEntity(contextToApplyState, entity);
}
}
/// <summary>
/// Clones the given Entity and attaches it to this DomainContext.
/// </summary>
/// <param name="contextToAttach"></param>
/// <param name="graph"></param>
/// <remarks>This only currently works for Entities with an integer
/// Key value</remarks>
public static void CloneEntityGraphAndAttach
(
this DomainContext contextToAttach,
EntityGraph graph
)
{
Entity clone = graph.Clone();
// Attach a clone of the entity graph to the temporary domain context
contextToAttach.EntityContainer.GetEntitySet(clone.GetType())
.Attach(clone);
// Apply the state of each entity to the cloned entity
foreach (Entity realEntity in graph)
{
ApplyStateToMatchingEntity(contextToAttach, realEntity);
}
}
/// <summary>
/// Applies the state of the given entity to the matching clone
/// in this DomainContext.
/// </summary>
/// <param name="domainContextToSearch"></param>
/// <param name="realEntity"></param>
/// <remarks>This only currently works for Entities with an
/// integer Key value</remarks>
public static void ApplyStateToMatchingEntity
(
this DomainContext domainContextToSearch,
Entity realEntity
)
{
FindMatchingEntity(domainContextToSearch, realEntity)
.ApplyState(realEntity.ExtractState
(RiaServicesContrib.ExtractType.OriginalState),
realEntity.ExtractState
(RiaServicesContrib.ExtractType.ModifiedState));
}
/// <summary>
/// Finds an entity with the same Key as the given entity
/// </summary>
/// <param name="realEntity"></param>
/// <param name="domainContextToSearch"></param>
/// <returns>The matching Entity, or null if not found</returns>
/// <remarks>This only currently works for Entities with an
/// integer Key value</remarks>
public static Entity FindMatchingEntity
(
this DomainContext domainContextToSearch,
Entity realEntity
)
{
// Find the entity set holding the clone
EntitySet entitySet = domainContextToSearch.EntityContainer
.GetEntitySet(realEntity.GetType());
// Find the clone within this entity set...
IEnumerator enumerator = entitySet.GetEnumerator();
// Find the Key property for the Entity
PropertyInfo keyProperty = null;
PropertyInfo[] properties = entitySet.EntityType.GetProperties();
foreach (PropertyInfo propertyInfo in properties)
{
foreach (Attribute attribute in entitySet.EntityType
.GetProperty(propertyInfo.Name).GetCustomAttributes(false))
{
if (attribute.GetType() == typeof(KeyAttribute))
{
keyProperty = propertyInfo;
break;
}
}
}
// Use the key property to find the clone with the same Id
while (enumerator.MoveNext())
{
Entity candidate = enumerator.Current as Entity;
if ((int)keyProperty.GetValue(candidate, null) ==
(int)keyProperty.GetValue(realEntity, null))
{
return candidate;
}
}
return null;
}
}
}
Subscribe to:
Posts (Atom)