Since no one has jumped on this one I went out and started reading from misc sources on the web to piece together what EF4 seems to be. I'll paste my sources here if anyone in the future needs to do this sort of investigation.
Here's a rant on NH vs. EF that is verbose but discusses some interesting topics.
Microsoft's own documentation on EF is here and was somewhat helpful although completely ignored the POCO mapping and fluent mappings that seem to be more NH-like.
There is a new addition to EF pending that seems to mimic fluent NH mappings. Here's a good, simple article/overview of that feature and here's a link to the latest Microsoft CTP code-first site.
Entity SQL is the equivalent to HQL.
Stored procedure mapping and execution is called "function mapping" and is very similar to how Linq to SQL did it, except that now there is reportedly much less possibility of being stuck with an unknown result type since you can be explicit about returning nothing, a scalar, a complex type or an entity. Here's an extra link on sp mapping for EF4.
There seems to be multiple ways to map your model. Using an EDMX designer is the completely automated way and seems excellent for smaller projects where absolute control of the mappings is overkill.
There are several ways to query, the most developer friendly seems to be LINQ to Entities and is of course like LINQ to NH.
Here's another POCO mapping example.
Overall the current state of EF feels more like LINQ to SQL than NHibernate, but considering how easy L2S is to use and Microsoft's ongoing investment in EF this seems like a good place to start.
Finally, since I am a developer I couldn't resist taking it for a test drive. Here's my tip of the iceberg exploration. SQL Profiler confirmed that eager/lazy loading works as advertised and that the update only updates changed fields.
// LINQ QUERY
using (MsgEntities ctx = new MsgEntities()) {
return (from m in ctx.Messages
where m.SentAt.Month == 11
select m).ToList();
}
// GET ONE WITH OBJECT GRAPH
Message msg = null;
MsgEntities ctx = new MsgEntities();
msg = ctx.Messages // .Include("MessageAttachments.Attachment") -uncomment for eager loading
.Where(m => m.PK_Message == PK_Message).SingleOrDefault();
// ADD
using (MsgEntities ctx = new MsgEntities()) {
ctx.Messages.AddObject(new Message() {
Dsc = "added message @ " + DateTime.Now.ToString("dd-MMM-yy HH:mm:ss"),
OriginalRecipientDsc = "Tahbaza",
Sender = "Tahbaza",
SentAt = new DateTime(2008, 11, 15),
Subject = "Nothing special"
});
}
// UPDATE
Message m = GetOneMessage(3);
using (MsgEntities ctx = new MsgEntities()) {
ctx.Attach(m);
m.Subject = "message UPDATED @ " + DateTime.Now.ToString("dd-MMM-yy HH:mm:ss");
ctx.SaveChanges();
}
// DELETE
Message m = GetOneMessage(3);
using (MsgEntities ctx = new MsgEntities()) {
ctx.Attach(m);
ctx.DeleteObject(m);
ctx.SaveChanges();
}
I hope this helps someone where I was 2 days ago.