I promise not to say anything along the lines of “it’s about time“. I promise! I won’t!
(And you can blame Cicero for that little trick I learned in Latin class many years ago…)
I promise not to say anything along the lines of “it’s about time“. I promise! I won’t!
(And you can blame Cicero for that little trick I learned in Latin class many years ago…)
I glanced at this headline:
Train Derails In Ohio; Explosion Heard
and thought it said
Train Derails In Ohio; Expression Blend
I know that your brain definitely fills in the blanks for you a lot which is why the SHAPE of words plays a huge role in being able to speed read. But I’d say this was a little bit out of context.
I learned a harsh lesson about Visual Studio and saving code snippets in the toolbox yesterday. Knowing that I am not great at coding Entity SQL on the fly, I stuck my code for custom operations in an Astoria Web data service into the VS2008 toolbox. I had two instances of VS open when I did this, so when I closed the instance where I had created the snippets, the instance that was still open is the one that saved the state and they were lost. Note to self: always have a text file with all snippets available when demoing. Oddly, I never used to trust the snippets and only used text files. I guess I need to get back to a level of cautious (though not rampant) mistrust.
I did surprise myself this morning when I rewrote these from memory and only made one mistake… inserting an “@” where I didn’t need to. I’d call that an A-. It wasn’t a typo, though and it did take a few minute to discover the error which is something I don’t like doing during a conference session, so I just skipped the pain. (Still only a C+ in my book đ ).
So here, in place of that particular demo, is a post on how to write operations in data services.
The default service provides for all of the capabilities of drilling into, traversing and querying your entities as laid out in this post and in more detail in the Using Astoria document that comes with the downloads and is also on the Astoria site. (Start at http://astoria.mslivelabs.com to find all resources.)
However you can customize your service by providing explicit query operations and also blocking specific query operations. Don’t forget that you can also build views and sprocs into your model. Views are surfaced as EntitySets so they will be no different than other entities (though read-only) in your web service. Stored Procs are a little different. I have to explore how both of those are currently surfaced in Astoria, but would like to wait until we have bits that are not just prototype.
To create a custom operation you need to use the WebGet attribute. Here’s an operation that finds all customers based on the first name of the contact. (I’m using the AW LT database, and am just lazily querying for something that is a direct property of the customer table.)
<WebGet()> _
Public Shared Function CustbyContact(ByVal aw As AdventureWorksLTEntities, ByVal firstname As String) As ObjectQuery(Of Customer)
If String.IsNullOrEmpty(firstname) Then
‘don’t expect to see this nice error if you are testing
‘your services in a browser
Throw New ArgumentNullException(“firstname”, _
“You must provide a name to search on”)
End If
Try
Return aw.Customer.Where(“it.firstname=@fname”, New ObjectParameter(“fname”, firstname))
Catch ex As ArgumentException
‘this is an opportunity to catch problems with your Entity SQL query when debugging
Throw ex
End Try
End Function
Note that I’m using Entity SQL in this query. While the query
http://localhost:50000/WebDataService1.svc/CustbyContact?firstname=Lindawill work if I had used LINQ to Entities for the query, I found that further operators or options such as this example where I additionally sort the response data
http://localhost:50000/WebDataService1.svc/CustbyContact?firstname=Linda&$orderby=CompanyName
do not work unless I have used Entity SQL.
While I have used a WebGet attribute to add additional queries to my service, you can use OnSendEntity and OnReceiveEntity to trap calls to the web service.
This custom operation in my data service prevents any one from querying directly for SalesOrderHeader entities using http://localhost:50000/WebDataService1.svc/SalesOrderHeader.
<OnSendEntity(“SalesOrderHeader”)> _
Public Shared Function RequestOrders(ByVal aw As AdventureWorksLTEntities, ByVal order As SalesOrderHeader) As Boolean
Return False
End Function
The using astoria doc details the key components for creating a method that traps requests and also one that traps POST, PUT and DELETE operations.
I’m hopping in the car to drive the 4 hours to Boston forthe sold-out REMIX which started this morning. I’ll be there all day tomorrow and will be giving a talk on Astoria tomorrow afternoon.
For you locals, the Vermont.NET user group is having a special type of meeting tonight – a PubClub! We’ll (without me – so You’ll) be meeting at RiRa’s in downtown Burlington. Check the website www.vtdotnet.org for details.
Thanks to Laura Blood, Tom Cooley and Rob Hale for coordinating and leading the three discussion topics.
Two job openings at Competitive Computing:
Contact: jobs@competitive.com
SENIOR BUSINESS ANALYST / PROJECT LEAD
We are looking for a highly-motivated, results-oriented Senior Business Analyst/Project Lead who will be responsible for delivery of software solutions for our clients. To deliver best practice technical solutions and business value to our clients, this position requires demonstrated leadership skills in IT project management as well as a personality that thrives in a continually changing technology landscape.
The ideal candidate will be a self-starter with the ability to work on a variety of assignments with people at all levels of the clientâs organization, leading business/system requirements analysis and application development for several large client projects. Managing clientsâ expectations and internal team performance throughout the project lifecycle is a core responsibility. The successful candidate also will need to build strong partnerships across those groups while acting as a key liaison between the technical and business members of both internal and client teams.
Required qualifications:
¡ Bachelor’s degree in Information Technology or related field, or equivalent along with 5+ years leadership experience in technical systems analysis and development.
¡ Very strong business analysis, analytical and problem solving skills, with solid data analysis skills.
¡ Excellent written and oral communications and influencing skills, with skills in consensus building and facilitation.
¡ Experience using Software Development Life Cycle methodology, to gather/document business, functional and data requirements, in accordance to Object Oriented Analysis & Design (OOAD) guidelines, and in developing/managing delivery of Use Cases.
¡ Experience managing project schedules and resources using Microsoft Project or other project management tool.
¡ Ability to work independently and proactively with a minimum amount of supervision, working within a collaborative team environment and with senior level business executives.
¡ Experience with large scale system development, business re-engineering, and project leadership experience are a plus.
SENIOR SOFTWARE ENGINEER / TECHNICAL ARCHITECT
C2 is seeking a senior-level software engineer/technical architect to lead design, architecture, and development of custom application development solutions for large client projects. The successful candidate will have previous experience with ASP.NET (C#) development, with a strong background in web-based development, object-oriented concepts, relational database design, and SQL Server development. Strong hands-on application architecture and design skills are required for the position, with excellent written and verbal communications. Previous experience on large client projects and technical presentation skills are pluses.
Bachelor’s degree preferred, Associate’s degree considered, along with 5-7 years experience in an application development environment.In addition to a competitive compensation and benefits package, C2 also promotes opportunities to advance technical knowledge through industry certifications, technical conferences, and other training programs. For those seeking significant growth potential, this is a unique opportunity to join a local company and work on challenging projects in a highly collaborative team environment.
Associate â Software Development
This position involves working in the Technology Group, supporting the firmâs software and analysis needs. The primary focus will be developing fully dynamic web-based solutions from interface to business logic to back end database design. We are looking for someone who is organized, resourceful, and analytical to join our team.
¡ Bachelorâs degree with emphasis in computer science or a related field
¡ Practical experience in the following areas:
o Web Development in HTML and CSS
o Database programming in SQL
o Modern object-oriented programming (e.g. C#, VB.Net, Java)
Please send resume and cover letter to Recruiting Director at employment@rsginc.com and indicate Associate Software Development in the subject heading.
I wanted to create a demo of Astoria Data Services being used in a Silverlight app for my ReMix07 Boston session on Tuesday. i have created a little screencast of it in action. Read more here…
On January 26, 2008, the VT Software Developers Alliance, CEDO, Champlain College, Seven Days, VSAC, the Lake Champlain Regional Chamber of Commerce and GBIC, along with many other partners is hosting an all day “Creative/Technology Career Jam” at the Lake & College Building on the Waterfront. We are hoping to attract at least 30 employers to set up booths and meet with high school, college students and adults to discuss the growing need for qualified technical employees.
This event will include food, music, and keynote and educational seminars presented by respected technology professionals, well known in their fields. Booth spaces will be $150 for 20 or less employees and $350 for more than 20 employees with limited space available. There will also be sponsorship opportunities. The rate sheet is not yet available, but please contact Bruce Seifer of CEDO (bseifer@ci.burlington.vt.us) or Patrick Martell with vtSDA (patrick@vtsda.org) if you are interested.
I’ve been playing with using EF object in code-behind of aspx web pages.
The first issue to hit is postbacks.
Entity Objects are Binary Serializable so they can be stored in ViewState.
Like many other objects, you need to put your entities into viewstate (I’ll deal with session and application caching in another post). Happily entities can be binary serialized so that happens for free when you add an entity object to ViewState. So you can persist the entities, but you cannot persist the ObjectContext, which is where all of the state information for the objects lives. Frankly, the objectcontext is very expensive and you wouldn’t want that in viewstate anyway.
The outcome of this is that even if you store the objects in viewstate, and pull them back out to attach to a new ObjectContext when you need them again, you will lose any state for the objects.
One saving grace is that objects stored in viewstate get updated automagically during postback. In other words, if I create a cust object and store it in viewstate, then make a change to the cust object, then postback and pull the object back out of viewstate, it will have the newer property values. Viewstate is synced up to the object.
That means we can be sure to have a current version of the object (or list of objects) hanging around as we muck with the page.
Binary Serialization keeps the entire graph in tact
The next piece of the puzzle is that if you have an obect graph (i.e. order with order details or cust with orders with orderdetails) that all gets persisted during binary serialization. That’s a big difference from xml serialization. The big reason is that XML serialization doesn’t know what to do with the relationships, which are also first class objets. The relationships “contain” all of the related data. So binary serialization can handle this. When you get the object graph out of viewstate, it’s got everything in it that it had when it went in.
Updating related data in an object that is in viewstate
This doesn’t act the way you might expect so listen up.
Say I have a cust object that has orders in it. i have saved the cust object into viewstate. If I edit a property of cust, say FirstName, that’s easy:
cust.FirstName=”Julie”
Viewstate syncs up that change just before the postback.
But what if I want to change something in one of the orders.
You need to do this directly in the cust object, not be extracting the order and changing it.
Here’s what I mean.
My first instinct is to do this:
myOrdtoEdit=(From ord in custs.Orders where ord.OrderID=123 Select ord).First()
myOrdtoedit.ShippedDate=”7/1/2007″
On postback, that new ShippedData is not there.
But if I make the change this way:
cust.Orders.Where(
Function(o) o.OrderID = currOrderid).First.ShippedDate=”7/1/2007″The change is synched up. Good to be aware of.
What about concurrency? What if I need to remember original values?
I think the real solution is going to be is to have original values cached in another layer. But for the sake of working out the concepts, let’s say you are doing everything in code behind. Here’s how I’m solving this problem.
When I first get the values, I want to store them in viewstate, too. But if I do that, and I want to take advantage of the synching viewstate (I think I remember seeing that there is a page directive to turn that off, but don’t hold me to it), then the original objects will get overwritten.
So what I have done was explicitly serialize the original objects and store the resulting memory stream into viewstate. When it’s time to do an update, I deserialize that stream and voila, I have a set of original objects that I can use to compare my current objects to.
I have a post here on how to do an update when you have the original object and current objects available over here.
One object or more? How do I persist multiple objects?
Note that I have wavered between talking about persisting a single object and multiple objects. If you are dealing with a query that returned a collection of objects, then you don’t persist the query. Instead, convert the query to a list with .ToList and you will end up with List<Customer> / List(Of Customer) and that’s what you can put into viewstate. This is also what you would serialize, the list of customer objects.
When do I work with the objects again?
I have done various tests using databinding (gridviews, textboxes) or just manually getting and setting text properties.
Once you post back, the datasource is gone on a bound control anyway. I just work with the text values that are in the control. When I want to update an object, then I will get the object(s) from viewstate and modify them. Other than that, the only time I need them again is when it’s time to do an update back to the data store.
And I missed it!
I was at a board meeting for www.vtsda.org, when Rich came home on Wednesday evening and saw a big male moose with BIG antlers sauntering up our road. When Rich got to our driveway he saw another moose… a girl.
The stage was set and luckily nobody got in the male’s way. It is pretty dangerous to get in the way of a male during rutting season; he will knock you down and trample you. Eventually the girl wandered off into our woods and the boy followed her. Luckily they were moving slowly,so most of our neighbors got a chance to see them.
Nobody got a picture.