Posts Tagged ‘Visual Studio’
Some databases behave according to standard so without quoting (which is a good way to hell), you got all in uppercase in your new shinny model generated from database (and yes, you should start modeling in empty model and define mapping later – just not to be screwed with relational world). Anyway a lot of people, including me, is generating model from database and then changing it.
But spending first hour or so of your work with renaming entities (or properties …) isn’t much fun. With same experience came guys from SMS-Timing, because they’re testing Entity Framework support for Firebird right now (and Firebird is behaving according to standard in this). Hence I’ve got the idea to make these identifiers little bit more code and developer friendly.
Because the *.EDMX file is just a couple of XML files together (CSDL, MSL, SSDL and designer stuff) you can tweak it by hand or by simple program. To get rid of all in uppercase I’ve created simple code (or program if you compile it yourself). It’s a simple program transforming names of entities to titlecase and also removing underscores with capitalizing next character.
static void Main(string[] args)
{
if (args.Length != 2)
return;
if (!File.Exists(args[0]))
return;
if (File.Exists(args[1]))
return;
XDocument xdoc = XDocument.Load(args[0]);
const string CSDLNamespace = "http://schemas.microsoft.com/ado/2006/04/edm";
const string MSLNamespace = "urn:schemas-microsoft-com:windows:storage:mapping:CS";
const string DiagramNamespace = "http://schemas.microsoft.com/ado/2007/06/edmx";
XElement csdl = xdoc.Descendants(XName.Get("Schema", CSDLNamespace)).First();
XElement msl = xdoc.Descendants(XName.Get("Mapping", MSLNamespace)).First();
XElement designerDiagram = xdoc.Descendants(XName.Get("Diagram", DiagramNamespace)).First();
Func<string, string> transformation = (string input) =>
{
Regex re = new Regex(@"(w+)(W*?)$", RegexOptions.None);
return re.Replace(input, new MatchEvaluator(
(Match m) =>
{
string replace = m.Groups[1].Value;
StringBuilder result = new StringBuilder(m.Length);
for (int i = 0; i < replace.Length; i++)
{
if ((i == 0) ||
(i > 0 && replace[i - 1] == '_'))
{
result.Append(char.ToUpper(replace[i]));
}
else if (replace[i] == '_')
{
continue;
}
else
{
result.Append(char.ToLower(replace[i]));
}
}
result.Append(m.Groups[2].Value);
return result.ToString();
}));
};
#region CSDL
foreach (var entitySet in csdl.Element(XName.Get("EntityContainer", CSDLNamespace)).Elements(XName.Get("EntitySet", CSDLNamespace)))
{
entitySet.Attribute("Name").Value = transformation(entitySet.Attribute("Name").Value);
entitySet.Attribute("EntityType").Value = transformation(entitySet.Attribute("EntityType").Value);
}
foreach (var associationSet in csdl.Element(XName.Get("EntityContainer", CSDLNamespace)).Elements(XName.Get("AssociationSet", CSDLNamespace)))
{
foreach (var end in associationSet.Elements(XName.Get("End", CSDLNamespace)))
{
end.Attribute("EntitySet").Value = transformation(end.Attribute("EntitySet").Value);
}
}
foreach (var entityType in csdl.Elements(XName.Get("EntityType", CSDLNamespace)))
{
entityType.Attribute("Name").Value = transformation(entityType.Attribute("Name").Value);
}
foreach (var association in csdl.Elements(XName.Get("Association", CSDLNamespace)))
{
foreach (var end in association.Elements(XName.Get("End", CSDLNamespace)))
{
end.Attribute("Type").Value = transformation(end.Attribute("Type").Value);
}
}
#endregion
#region MSL
foreach (var entitySetMapping in msl.Element(XName.Get("EntityContainerMapping", MSLNamespace)).Elements(XName.Get("EntitySetMapping", MSLNamespace)))
{
entitySetMapping.Attribute("Name").Value = transformation(entitySetMapping.Attribute("Name").Value);
foreach (var entityTypeMapping in entitySetMapping.Elements(XName.Get("EntityTypeMapping", MSLNamespace)))
{
entityTypeMapping.Attribute("TypeName").Value = transformation(entityTypeMapping.Attribute("TypeName").Value);
}
}
#endregion
#region Designer
foreach (var item in designerDiagram.Elements(XName.Get("EntityTypeShape", DiagramNamespace)))
{
item.Attribute("EntityType").Value = transformation(item.Attribute("EntityType").Value);
}
#endregion
using (XmlTextWriter writer = new XmlTextWriter(args[1], Encoding.Default))
{
xdoc.WriteTo(writer);
}
}
The code is pretty simple. It just goes to thru the file and changes what needs to be changed. Mainly CSDL and MSL parts. Changes in designer part are not necessary, but you’ll lose positions etc. when you don’t do it. This is kind of this-afternoon-code – maybe I forgot something, maybe the RE is matching too much… Feel free to report problems in comments.
If you want to change also names of properties you can either tweak the code yourself or ask in comments, if I found some time, I’ll extend it. And of course, if you have some special naming convention in your company (i.e. every table has T_ prefix), just change the transformation function.
Entity Framework support for Firebird had a problem, when you created model and then tried to update model (Update Model from Database) VS freeze. I was pretty sure, that’s a problem of server – because I was using 2.5 build from HEAD that cannot be considered as stable and the 2.1 was working fine (except the left outer join problem
) (because foreign keys/associations were not generated the problem wasn’t fired). And I was wrong.
Similar to problem I described on http://forums.microsoft.com/MSDN/ShowPost.aspx?siteid=1&PostID=3519267, the problem was in NULL in CatalogName in DefiningQuery in SSDL for store. Funny is that generating model from EdmGen and also in wizard was working fine, only updating was failing. But no exception, no error, nothing. Just freeze. If I had NULL in SchemaName I was getting exception in EdmGen leastways.
OK, now – just to be safe – CatalogName and also SchemaName isn’t NULL, but dummy string. No attempts to be smart.
Never mind, could be worse. Now it’s fixed, so you can grab build from http://netprovider.cincura.net/ and test it. Eh, and if you’re looking for some FB with fixed left outer join, check i.e. http://cid-bdb67deba4c656e5.skydrive.live.com/self.aspx/Ve%c5%99ejn%c3%a9/FB%7C_FixedLeftOuterJoin/Firebird-2.5.0.21381-0%7C_Win32.zip, it’s a snapshot of current 2.5 trunk.
This problem itself has been also discussed in comments here.
What’s better than finding what you need to fix for upcoming release of product?
I get finally Visual Studio 2010 CTP up and running and decided to test whether DDEX provider for Firebird is working fine with it (else I need to find why not and fix these issues). Luckily it’s working fine. I’ve changed reg files appropriately for VS2010 and modified machine.config for .NET FW 4.0. No problem, 10 minutes and it was done.
Check this out. Nice, isn’t it?

Při všem shonu okolo PDC a Windows 7, Azure aspol. jsem úplně minul ohlášení o novém logu pro .NET. Posuďte sami.

Není ošklivé, ale ani mě neposadilo na zadek. Takový dobrý standard dobrého grafika. Co myslíte?
Videa z PDC2008 jsou dostupná zdarma na Channel9. Není potřeba registrace.
Today I had some time and I spent it playing with associations mapping on custom objects. Adding new objects is easy. It’s what you already know. The only one new part is work with associations and navigation properties. But as always when you stuck you can generate dummy EDMX file and look at the result.
You can start from scratch and create all classes and so on as in previous article. But I’ll start where I ended, it’s little bit faster.
First thing you have to create is new class, related to our Product class. I’ll create ProductSize class that will hold info about the size of product (don’t try to find something useful on this, it’s just a simple example). The class will contain only ID and Size property. You can take inspiration from previous article, it’s almost same. What you have to add is an IEntityWithRelationships interface implementation to both classes. It’s same for both. This interface forces you to implement RelationshipManager member.
RelationshipManager IEntityWithRelationships.RelationshipManager
{
get
{
if (_relationships == null)
_relationships = RelationshipManager.Create(this);
return _relationships;
}
}
Now you have to either edit CSDL, MSL and SSDL files by hand (if your night reading is some *.edmx file) or generate these again using EdmGen/EdmGen2 and remove any unnecessary lines. Also you can rename some items to match your needs and class members (i.e. if you have NavigationProperty one-to-many on one side would be probably plural and on other side singular). Good checkpoint after this is to run EdmGen with ValidateArtifacts mode to uncover any problems.
After this you have to modify class that you get in previous article from custom tool usage. You have to apply EdmRelationshipAttribute using the assembly prefix, because it has AttributeTargets.Assembly as usage. When you use custom tool, it will be generated for you. When first trying to do the mapping I forgot about it and I lost half an hour of my time.
[assembly: EdmRelationship("CustomClasses_EDM", "FK_Products_ProductSizes", "ProductSizes", RelationshipMultiplicity.One, typeof(CustomClasses_EDM.ProductSize), "Products", RelationshipMultiplicity.Many, typeof(CustomClasses_EDM.Product))]
Now you only need to add navigation properties in your custom classes. Of course, you can add some properties to your ObjectContext class, similar to Products.
OK, first, apply EdmRelationshipNavigationProperty attribute to your navigation properties. For my Product object and ProductSize property it looks like this.
[EdmRelationshipNavigationProperty("CustomClasses_EDM", "FK_Products_ProductSizes", "ProductSizes")]
Let’s do the getter. You have to get RelationshipManager and use GetRelatedReference method. For my Products ⇒ ProductSizes direction you should end up with:
get
{
return ((IEntityWithRelationships)(this)).
RelationshipManager.
GetRelatedReference<ProductSize>("CustomClasses_EDM.FK_Products_ProductSizes", "ProductSizes").Value;
}
For other direction use the GetRelatedCollection method and no Value is used. The setter for Products ⇒ ProductSizes direction is just about assigning value to Value. For ProductSizes ⇒ Products it’s little bit different. You have to use InitializeRelatedCollection method to set new value.
((IEntityWithRelationships)(this)).
RelationshipManager.
InitializeRelatedCollection<Product>("CustomClasses_EDM.FK_Products_ProductSizes", "Products", value);
And maybe it’s good idea to check for nulls, because it’s not allowed to put it there (again, just fine-tuning).
Now when you try to run the code like:
var q = from p in ctx.Products
where p.ID < 200
select p;
foreach (Product p in q)
{
Console.WriteLine(p.Name);
Console.WriteLine("t" + p.ProductSize.Size);
}
You got exception. Yeah, lazy loading. You have to use, for example (Entity Framework Include with Func):
var q = from p in ctx.Products.Include("ProductSize")
where p.ID < 200
select p;
foreach (Product p in q)
{
Console.WriteLine(p.Name);
Console.WriteLine("t" + p.ProductSize.Size);
}
Using custom objects and associations with Entity Framework isn’t hard too. You generate three files from database, change it (which is maybe the hardest part – to match database to your objects) and small changes in objects. And you’re done.
Yet again, with POCO and persistence ignorance it will much easier. But it isn’t impossible now.
See also: How to map your custom objects in Entity Framework
Published on Databazovy Svet
Well, generating EDMX file from database and letting Visual Studio to generate all the objects is easy. But sometimes you have your custom objects with custom logic. How to solve this? In version 1 of Entity Framework this isn’t easy. It’s possible, but not easy. The good news is, that for version 2 there is huge amount of work on POCO (Plain Old CLR Objects) with persistence ignorance.
With current version you have, in general, two possible choices. The “easier” way is to derive from special object EntityObject. Anyway, this is probably what you don’t want, because you’re probably deriving from your own objects (and as we know multiple inheritance isn’t possible in C#). The other way is to implement some interfaces. It’s not so straightforward, but, at least in my opinion, more practical.
In our simple example we’ll be neither using complex types (it’s not so hard to add it) nor any associations (I’ll cover this later in other article). Let’s start with our class, I’ll call it Product and it’ll be very simple.
public class Product
{
private int _id;
private string _name;
private int _price;
public int ID
{
get { return _id; }
set { _id = value; }
}
public string Name
{
get { return _name; }
set { _name = value; }
}
public int Price
{
get { return _price; }
set { _price = value; }
}
}
As you can see, the class is really simple. You can imagine some logic i.e. on price or on name length. To make this object “tasty” for Entity Framework infrastructure you have to implement only one interface. It’s called IEntityWithChangeTracker. For associations support you should implement also IEntityWithRelationships. There’s also IEntityWithKey interface that forces you to implement EntityKey to improve performance and decrease memory usage. It’s just cherry on a pie.
The first noted interface implementation is pretty easy. You’ll just implement one method in easy way.
void IEntityWithChangeTracker.SetChangeTracker(IEntityChangeTracker changeTracker)
{
_changeTracker = changeTracker;
}
With complex types you have also set change tracker for these using SetComplexChangeTracker method.
To make change tracker working, we need to slightly change our setters. The setters should look like this for Name property.
set
{
if (_changeTracker != null)
_changeTracker.EntityMemberChanging("Name");
_name = value;
if (_changeTracker != null)
_changeTracker.EntityMemberChanged("Name");
}
Pretty simple, isn’t it? The last thing you have to change in your class is to add EdmScalarProperty attribute to ID, Name and Price members. That’s all you have to do with the class.
Now comes the tricky part (don’t be scared it’s not heavy magic
). First you need to get SSDL, MSL and CSDL files. These files contain store-schema, mapping and conceptual-schema definition. Although you can write these files by hand, using some tool is much faster. The easiest way is to generate these using EdmGen (or maybe EdmGen2). EdmGen is standard part of Entity Framework. Just use FullGeneration mode and provide /connectionstring and /project parameters. This gives you five files in result. Delete the two with *.cs extension, you don’t need it. With EdmGen you get complete mapping for whole database so you have to delete some unnecessary stuff. Leave there only lines related to Products table (or whatever your table named is). If you don’t understand content of these files, the best way is to generate *.edmx file in Visual Studio only for our table and look at the result (EDMX file is in fact just CSDL, MSL and SSDL together plus some other stuff. You can use i.e. EdmGen2 to extract these files. But EdmGen2 isn’t standard part of Entity Framework.) right-clicking on the file and choosing Open With... and XML Editor. After this tricky part add these files to your project. On CSDL file open Properties and use for Custom Tool EntityModelCodeGenerator. This generates you new file under CSDL file. Copy content into new file and remove the Custom Tool definition. This new file contains implementation of ObjectContext class and also Products class. You can delete Products class (or class for your table), because we have ours. The last step is to replace occurrences of Products that has been removed, by Product, which is our class (you can use Products (plural), where it makes sense, of course). So the result can look like this.
public global::System.Data.Objects.ObjectQuery<Product> Products
{
get
{
if ((this._Products == null))
{
this._Products = base.CreateQuery<Product>("[Product]");
}
return this._Products;
}
}
private global::System.Data.Objects.ObjectQuery<Product> _Products;
public void AddToProducts(Product product)
{
base.AddObject("Product", product);
}
You can also change the first constructor, if you’re interested.
After this you can use standard ways to query or update the Products table. You have to provide “entity frameworkish” connection string to make it work. The first option is to embed CSDL, MSL and SSDL files into resources and use res://<assemblyFullName>/<resourceName> specification in connection string (more info on http://msdn.microsoft.com/en-us/library/cc716756.aspx) or simply copy these three files into some folder and use path. My choice was the second (copying files into same folder as executable), so my code looks like (using MS SQL Express):
CustomClasses_EDMContext ctx = new CustomClasses_EDMContext("metadata=CustomClasses_EDM.csdl|CustomClasses_EDM.ssdl|CustomClasses_EDM.msl;provider=System.Data.SqlClient;provider connection string="Data Source=.\sqlexpress;Initial Catalog=test;Integrated Security=True"");
var q = from p in ctx.Products
where p.ID < 200
select p;
foreach (Product p in q)
{
Console.WriteLine(p.Name);
p.Name = p.Name + "R";
}
ctx.AddToProducts(new Product() { Name = "New Product", Price = 999 });
ctx.SaveChanges();
When you try to run this example, you’ll be able not even to enumerate items in table (products), but also to update, add etc. it.
It’s not as fast as using designer, you have to do some manual work (but I think you can write some tool to automate it and also EdmGen2 will help), however you’re using your custom objects (without rewriting these completely).
The work on POCO and persistence ignorance in version 2 of Entity Framework will be a step forward, no doubts, but this isn’t too bad isn’t it?
See also: How to use custom objects with associations in Entity Framework
Published on Databazovy Svet
As you (maybe) know, there was a bug in left outer join so the model generation/update etc. in Entity Framework and similar tools was failing. The bug is now gone. Well, it’s not in some oficial release, but it’s in sources. If you want to test it, grab sources and build or grab this build (only SuperServer executable). Also take into accout, that it’s build from current sources and can be very unstable.
The final version of SP1 for VS2008 and .NET 3.5 is out for a while. And you may noticed, that there were some changes between SP1 beta and SP1 final. These changes are happily not huge as between EF Beta 3 and SP1 Beta 1.
So if you want to test new version of FirebirdClient working with SP1 check the weekly builds.
- SP1 for .NET 3.5 is available here.
- SP1 for VS 2008 is available here.
The SP1 contains also Entity Framework.
MS Sync Framework v1.0 is ready for download.
Today I get error “The operation could not be completed” when I was trying to open *.dbml LINQ to SQL file. I have this developement environment in virtual machine and I did no installs or updates. Event Log also wasn’t saying anything that could help. First classic shoots like restart, cleaning all temps, caches etc. – nothing. Still same problem.
I’ve tried to add new dbml to project (in worst case, I was ready to copy to content of files, because build was OK). Heureka, designer opened like a charm. But,
when I dropped some table on designer’s surface I got error “Exception has been thrown by the target of an invocation.”. Hmm, damn.
Thanks my paranoia I have backups of a lot of stuff, virtuals too. 1-2 hours of installing and I was back. When configuring my new-old machine everything worked fine. So I’ve installed some experimental stuff like Entity Framework beta, some VS updates required and added DDEX for Firebird. Just quick click-click-next-next. I opened the project and wanted to open dbml file, oh, the error was back again.
After this, I incidentally realised, that I’ve removed FirebirdClient assembly from GAC after installing DDEX. To make DDEX work I’ve installed 2.1 version, ’cause I have it built. But for testing Entity Framework support I’m using 2.5.x version and I was planning to add it later, ’cause I had no built assembly near my hands. Exactly this (removing FirebirdClient from GAC) I did few days ago, when I was debugging some reported issue. And that was the problem! How innocent and how devastating.
Adding assembly back to GAC solved the problem. Hope this helps somebody.
Wish I’ve found it sooner and saved time with copying and installing stuff.
Tak a je to. Entity Framework a ADO.NET Data Services budou součástí SP1 pro VS2008 a .NET 3.5. Paráda. Doufám, že do té doby dokončím i podporu pro Entity Framework v ADO.NET provideru pro Firebird.
There’s a neat feature in Visual Studio 2008 (in 2005 too). When you type some object name, i.e. Regex, you can see small red dash at the end of the word. Pressing Ctrl+. gives you menu, where you can add namespace to using block or use full name on current line.

Nice and useful feature.
We’re moving, slowly, step-by-step. And new functionality is coming in view. Just two pictures showing a piece of functionality. Yes, it’s a “LINQ to Firebird”, in fact LINQ to Entites connected to Firebird.

Just a small taste of Entity Framework using Firebird. Nothing else is working (and probably something is doing what it shouldn’t).
Compiled right now.

First steps are always problematic. But without help from these guys (from Microsoft): David Sceppa, Jaroslaw Kowalski and Mike Kaufman I wouldn’t finish this “a little bit working stub”. Thank you guys!
I hope to show you, Firebird and .NET fans, better working versions in a near future.