Sneak Peek – Using Code Generation Templates with the Entity Framework 4.0
Entity framework 4.0'ın en önemli yeniliklerinden biri olan POCO entity desteği. Özellikle EF 3.5 ile oluşturulan Entity Model ve onunla oluşan entityler, servislerde serialization problemlerine neden olmaktaydı ki nedeni entity objesinin üzerinde EF'ye ait relation gibi attribute'ların olmasıydı. İşte tam bu noktada EF 4.0 imdada yetişiyor. Ancak EF 4.0 ile POCO Entity leri oluşturmak için manuel bi kaç değişiklik gerekiyo ve Entitylerin oluşması için de T4 template generator'ın kullanılması gerek. Neyse ki bu vs 2010 template'lerinde var ve Edmx Designer'dan çağrılabiliyo. Detaylı bilgi için orjinal döküman linki aşağıdadır.
Published 19 May 09 01:42 PM | dpblogs
In the first version of the Entity Framework code generation was implemented internally using CodeDom. The Entity Framework APIs provided some hooks for customizing the generation, but customizing was tricky, relatively inflexible and wasn’t integrated into Visual Studio.
In .NET 4.0 all these limitations go away.
The Entity Framework now leverages T4, Text Template Transformation Toolkit, which makes customizing Code Generation easy, flexible and powerful, and the experience is also fully integrated into Visual Studio.
T4 itself is very simple, in fact you can try it out in Visual Studio 2008 today if you want. T4 provides a clean way of interleaving control logic and references to variables with output text, that is reminiscent of the techniques used widely in web server programming (for those familiar with old-school ASP or ASP.NET MVC views it will look vaguely familiar).
Out of the box the Entity Framework will ship with two T4 templates, both of which will produce EntityObject derived Entities. One in VB that produces VB code, and one in C# that produces, yes you guessed it, C# code.
Orjinal yazı için...
28 Kasım 2009 Cumartesi
Entity Framework 4.0: Pluralization
One of the new features in Entity Framework 4.0 (EF v2) is a service call “Pluralization”. This service is used to convert names of objects form singular and/or plural forms. For instance, if you have a table in the database that has a plural name such as “Customers”, then Entity Framework will automatically generate both object Name and Entity Set Name to “Customers” as well. The result is that in your code, the name will look like this:
Customers c = new Customers();
Ideally, it would have been nice for EF to see that the table was a plural name and set the object Name to a singular form.
Now, you may be thinking that this is pretty trivial since you can manually change the generated name, but when when you have dozens or hundreds of tables this can be tedious at best.
To use the PluralizationService when generating an Entity Framework model, you just select the option"Pluralize or singularize generated object names”
Orjinal yazı için...
Customers c = new Customers();
Ideally, it would have been nice for EF to see that the table was a plural name and set the object Name to a singular form.
Now, you may be thinking that this is pretty trivial since you can manually change the generated name, but when when you have dozens or hundreds of tables this can be tedious at best.
To use the PluralizationService when generating an Entity Framework model, you just select the option"Pluralize or singularize generated object names”
Orjinal yazı için...
.NET 4.0 and Lazy
.NET 4.0 is so Lazy
With .NET 4.0 there is a new class added to the System namespace called Lazy. This class is what the name says, lazy. Here is an example where Lazy is used:
var lazy = new Lazy>(
() =>
{
var rows = //get order rows;
return rows;
});
var rows = lazy.Value;
The Lazy’s constructor can take a Func as an argument, the function passed as an argument to the contractor will first be invoked when the Value property of the Lazy class is used, but not invoked the next time the Value property is used. The code above will first execute the function passed as an argument when the we request the value of the Lazy, the returned value of the function will be cached. The next time Value is used, the function will not be invoked, instead the cached value will be returned. This class can for example be used when we want some kind of Lazy Loading.
Beware of the Lazy .NET 4.0 type. The closure trap.
The System.Lazy type in the new .NET 4.0 framework came to my attention recently. This type is not at all revolutionary. In fact, everyone could have written it themselves in under 10 lines of code going as far back as the .NET 2.0 framework.
Some less experienced programmers won’t realize however, that deferring the call to a delegate could have nasty side effects.
Consider the following code snippet:
01
static void Main(string[] args)
02
{
03
List> lazyInit = new List>();
04
for (char letter = 'A'; letter <= 'Z'; letter++)
05
{
06
var lazy = new Lazy(() => letter.ToString());
07
lazyInit.Add(lazy);
08
}
09
foreach (var lazy in lazyInit)
10
{
11
Console.Write(lazy.Value);
12
}
13
Console.ReadLine();
14
}
The code is pretty straight forward, but what gets printed here? Would you think it’s the alphabet? You would be very wrong.
The output is exactly ‘ZZZZZZZZZZZZZZZZZZZZZZZZZ’. Go ahead, run it yourself if you don’t trust me.
To understand why this happens, you need to understand how closures work.
In the constructor to the Lazy<> class, you’re passing in a delegate, in the form of a lambda. This delegate captures the letter variable (attention, not its value at the time of the call, but the variable as a whole) and creates a closure class around it behind the scenes. This may be counter-intuitive to the average programmer. For further information on what happens behind the scenes with captured variables and closures, read this great post by Marc Gravell.
This is not specific behavior of the new Lazy class, it’s what happens every time a delegate is stored for deferred execution.
If you rewrite the code without deferred execution, you’ll see that the problem doesn’t manifest itself:
01
static void Main(string[] args)
02
{
03
for (char letter = 'A'; letter <= 'Z'; letter++)
04
{
05
var lazy = new Lazy(() => letter.ToString());
06
Console.Write(lazy.Value);
07
}
08
Console.ReadLine();
09
}
10
// Output: ABCDEFGHIJKLMNOPQRSTUVWXYZ
Same delegate is being used, but it is executed immediately. The output is now the complete English alphabet, as you would expect.
This isn’t very useful however, We’ve completely thrown away the advantages of the Lazy class and we might as well not be using it.
So, how can we fix it? We need to use an intermediary variable inside the body of the for loop that is simply a copy of the outer variable. The inner variable’s scope is unique to each loop iteration, so it matters a whole lot where you define your variables.
Fixed code:
01
static void Main(string[] args)
02
{
03
List> lazyInit = new List>();
04
05
// char letter2; // <- for the sake of exercise, uncomment this line and remove the ‘char’ keyword from the initialization of the letter2 variable inside the for loop below. the ‘bug’ will manifest itself again
06
for (char letter = 'A'; letter <= 'Z'; letter++)
07
{
08
char letter2 = letter; // value re-captured in inner block (remove ‘char’ keyword and uncomment line above to see the ‘bug’ manifest itself again)
09
var lazy = new Lazy(() => letter2.ToString());
10
lazyInit.Add(lazy);
11
}
12
foreach (var lazy in lazyInit)
13
{
14
Console.Write(lazy.Value);
15
}
16
Console.ReadLine();
17
}
One tool that can automatically check for this condition so you can avoid headaches later is JetBrain’s Resharper. With Resharper installed, you’d see a warning underneath () => letter.ToString() which spells ‘Access to modified closure’ and suggests the same fix I described in this blog post.
If anyone’s interested in seeing how the same Lazy class could be implemented in .NET 2.0 and up, leave a comment and I’ll post it here!
With .NET 4.0 there is a new class added to the System namespace called Lazy
var lazy = new Lazy
() =>
{
var rows = //get order rows;
return rows;
});
var rows = lazy.Value;
The Lazy
Beware of the Lazy
The System.Lazy
Some less experienced programmers won’t realize however, that deferring the call to a delegate could have nasty side effects.
Consider the following code snippet:
01
static void Main(string[] args)
02
{
03
List
04
for (char letter = 'A'; letter <= 'Z'; letter++)
05
{
06
var lazy = new Lazy
07
lazyInit.Add(lazy);
08
}
09
foreach (var lazy in lazyInit)
10
{
11
Console.Write(lazy.Value);
12
}
13
Console.ReadLine();
14
}
The code is pretty straight forward, but what gets printed here? Would you think it’s the alphabet? You would be very wrong.
The output is exactly ‘ZZZZZZZZZZZZZZZZZZZZZZZZZ’. Go ahead, run it yourself if you don’t trust me.
To understand why this happens, you need to understand how closures work.
In the constructor to the Lazy<> class, you’re passing in a delegate, in the form of a lambda. This delegate captures the letter variable (attention, not its value at the time of the call, but the variable as a whole) and creates a closure class around it behind the scenes. This may be counter-intuitive to the average programmer. For further information on what happens behind the scenes with captured variables and closures, read this great post by Marc Gravell.
This is not specific behavior of the new Lazy
If you rewrite the code without deferred execution, you’ll see that the problem doesn’t manifest itself:
01
static void Main(string[] args)
02
{
03
for (char letter = 'A'; letter <= 'Z'; letter++)
04
{
05
var lazy = new Lazy
06
Console.Write(lazy.Value);
07
}
08
Console.ReadLine();
09
}
10
// Output: ABCDEFGHIJKLMNOPQRSTUVWXYZ
Same delegate is being used, but it is executed immediately. The output is now the complete English alphabet, as you would expect.
This isn’t very useful however, We’ve completely thrown away the advantages of the Lazy
So, how can we fix it? We need to use an intermediary variable inside the body of the for loop that is simply a copy of the outer variable. The inner variable’s scope is unique to each loop iteration, so it matters a whole lot where you define your variables.
Fixed code:
01
static void Main(string[] args)
02
{
03
List
04
05
// char letter2; // <- for the sake of exercise, uncomment this line and remove the ‘char’ keyword from the initialization of the letter2 variable inside the for loop below. the ‘bug’ will manifest itself again
06
for (char letter = 'A'; letter <= 'Z'; letter++)
07
{
08
char letter2 = letter; // value re-captured in inner block (remove ‘char’ keyword and uncomment line above to see the ‘bug’ manifest itself again)
09
var lazy = new Lazy
10
lazyInit.Add(lazy);
11
}
12
foreach (var lazy in lazyInit)
13
{
14
Console.Write(lazy.Value);
15
}
16
Console.ReadLine();
17
}
One tool that can automatically check for this condition so you can avoid headaches later is JetBrain’s Resharper. With Resharper installed, you’d see a warning underneath () => letter.ToString() which spells ‘Access to modified closure’ and suggests the same fix I described in this blog post.
If anyone’s interested in seeing how the same Lazy
Entity Framework 4.0 Resources – documentation links, best blog posts and more
Entity Framework 4.0 için güzel bir kaynak. Bakmakta fayda var :)
Entity Framework 4.0 Resources – documentation links, best blog posts and more
This is one of a series of posts on my preparations for sessions on Azure and ORMs at Software Architect 2009.
[Initual release 22nd Sept 2009]
[Updated 23rd Sept, with links from Julie Lerman]
[Updated 2nd Oct, with slidedeck section]
This is my attempt to pull together all (ok – most) of the improvements in Entity Framework 4.0 and aggregate useful resources against each. It is very much work in progress – but is hopefully already fairly helpful.
Some of the links are to early posts which came out pre VS2010 Beta 1. These should be treated with caution as a lot changed since they were written – but they often start with a good introduction to the topic and hence I felt they were worth including.
Entity Framework 4.0 Resources – documentation links, best blog posts and more
This is one of a series of posts on my preparations for sessions on Azure and ORMs at Software Architect 2009.
[Initual release 22nd Sept 2009]
[Updated 23rd Sept, with links from Julie Lerman]
[Updated 2nd Oct, with slidedeck section]
This is my attempt to pull together all (ok – most) of the improvements in Entity Framework 4.0 and aggregate useful resources against each. It is very much work in progress – but is hopefully already fairly helpful.
Some of the links are to early posts which came out pre VS2010 Beta 1. These should be treated with caution as a lot changed since they were written – but they often start with a good introduction to the topic and hence I felt they were worth including.
Problem attaching a database
CREATE FILE encountered operating system error 5(error not found) while attempting to open or create the physical file ''. (.Net SqlClient Data Provider)
Sql Server Management Studio aracılığı ile bi mdf 'i attach etmek istediğimde yukardaki hata ile karşılaştım. Sorun dosya erişim yetkisi :) çözümü link olarak verdim.
Sql Server Management Studio aracılığı ile bi mdf 'i attach etmek istediğimde yukardaki hata ile karşılaştım. Sorun dosya erişim yetkisi :) çözümü link olarak verdim.
4 Kasım 2009 Çarşamba
Dynamic in C# 4.0: Creating Wrappers with DynamicObject and ExpandoObject
C# 4.0 ile gelen dynamic'e ilk gördüğüm andan itibaren tutuldum :) Süper bişi.
Örn 1:
public class DynamicXMLNode : DynamicObject
{
XElement node;
public DynamicXMLNode(XElement node)
{
this.node = node;
}
public DynamicXMLNode()
{
}
public DynamicXMLNode(String name)
{
node = new XElement(name);
}
public override bool TrySetMember(
SetMemberBinder binder, object value)
{
XElement setNode = node.Element(binder.Name);
if (setNode != null)
setNode.SetValue(value);
else
{
if (value.GetType() == typeof(DynamicXMLNode))
node.Add(new XElement(binder.Name));
else
node.Add(new XElement(binder.Name, value));
}
return true;
}
public override bool TryGetMember(
GetMemberBinder binder, out object result)
{
XElement getNode = node.Element(binder.Name);
if (getNode != null)
{
result = new DynamicXMLNode(getNode);
return true;
}
else
{
result = null;
return false;
}
}
}
dynamic contact = new DynamicXMLNode("Contacts");
contact.Name = "Patrick Hines";
contact.Phone = "206-555-0144";
contact.Address = new DynamicXMLNode();
contact.Address.Street = "123 Main St";
contact.Address.City = "Mercer Island";
contact.Address.State = "WA";
contact.Address.Postal = "68402";
sonucuunda alınan çıktı:
XElement contactXML =
new XElement("Contact",
new XElement("Name", "Patrick Hines"),
new XElement("Phone", "206-555-0144"),
new XElement("Address",
new XElement("Street1", "123 Main St"),
new XElement("City", "Mercer Island"),
new XElement("State", "WA"),
new XElement("Postal", "68042")
)
);
Örn 2:
dynamic contacts = new List();
contacts.Add(new ExpandoObject());
contacts[0].Name = "Patrick Hines";
contacts[0].Phone = "206-555-0144";
contacts.Add(new ExpandoObject());
contacts[1].Name = "Ellen Adams";
contacts[1].Phone = "206-555-0155";
kullanımı da,
foreach (var c in contacts)
Console.WriteLine(c.Name);
var phones = from c in (contacts as List)
where c.Name == "Patrick Hines"
select c.Phone;
Kısaca örnekleri koydum, daha detaylı bilgi için belirttiğim kaynaklara başvurun :)
Örn 1:
public class DynamicXMLNode : DynamicObject
{
XElement node;
public DynamicXMLNode(XElement node)
{
this.node = node;
}
public DynamicXMLNode()
{
}
public DynamicXMLNode(String name)
{
node = new XElement(name);
}
public override bool TrySetMember(
SetMemberBinder binder, object value)
{
XElement setNode = node.Element(binder.Name);
if (setNode != null)
setNode.SetValue(value);
else
{
if (value.GetType() == typeof(DynamicXMLNode))
node.Add(new XElement(binder.Name));
else
node.Add(new XElement(binder.Name, value));
}
return true;
}
public override bool TryGetMember(
GetMemberBinder binder, out object result)
{
XElement getNode = node.Element(binder.Name);
if (getNode != null)
{
result = new DynamicXMLNode(getNode);
return true;
}
else
{
result = null;
return false;
}
}
}
dynamic contact = new DynamicXMLNode("Contacts");
contact.Name = "Patrick Hines";
contact.Phone = "206-555-0144";
contact.Address = new DynamicXMLNode();
contact.Address.Street = "123 Main St";
contact.Address.City = "Mercer Island";
contact.Address.State = "WA";
contact.Address.Postal = "68402";
sonucuunda alınan çıktı:
XElement contactXML =
new XElement("Contact",
new XElement("Name", "Patrick Hines"),
new XElement("Phone", "206-555-0144"),
new XElement("Address",
new XElement("Street1", "123 Main St"),
new XElement("City", "Mercer Island"),
new XElement("State", "WA"),
new XElement("Postal", "68042")
)
);
Örn 2:
dynamic contacts = new List
contacts.Add(new ExpandoObject());
contacts[0].Name = "Patrick Hines";
contacts[0].Phone = "206-555-0144";
contacts.Add(new ExpandoObject());
contacts[1].Name = "Ellen Adams";
contacts[1].Phone = "206-555-0155";
kullanımı da,
foreach (var c in contacts)
Console.WriteLine(c.Name);
var phones = from c in (contacts as List
where c.Name == "Patrick Hines"
select c.Phone;
Kısaca örnekleri koydum, daha detaylı bilgi için belirttiğim kaynaklara başvurun :)
Kaydol:
Kayıtlar (Atom)