Frank Dzaebel, erstellt am: 10.5.2008,
zuletzt geändert: 10.05.2008
Kategorie: LINQ to Entities,
.NET-Version: 3.5 SP1 Beta1, [Download]
In verteilten Szenarien ist ein Update eines Entities (ADO.NET
Entity Framework) nicht komplett trivial. Es gibt zwei Haupt-Techniken:
Technik 1: Übergabe eines geklonten Original-Objektes.
Technik 2: Das Original innerhalb der Update-Methode über einen (zusätzlichen) RoundTrip
vom Server holen.
Siehe dazu:
[How to:
Apply Changes Made to a Detached Object]
using System;
using System.Linq;
using System.Windows.Forms;
using System.ComponentModel;
using System.Text;
using FrankModel;
using System.Collections;
using System.Reflection;
using System.Data;
namespace EntityFirst
{
/// <summary>Client (in diesem Fall) ohne ObjectContext.</summary>
public partial class Client : Form
{
public Client()
{
InitializeComponent();
}
private void Client_Load(object sender, EventArgs e)
{
Person neue = Person.CreatePerson(1);
Person erste = Server.GetFirstPerson();
ObjectDumper.Write(erste);
ObjectDumper.Write(neue);
Person geänderte = erste.Clone();
geänderte.Alter = 13;
Person ersteOriginal = erste.Clone();
Server.UpdatePerson(geänderte, erste);
erste = Server.GetFirstPerson();
ObjectDumper.Write(erste);
}
}
/// <summary>Funktionalität simuliert Server bei verteilter Anwendung.</summary>
class Server
{
/// <summary>Gibt die erste Person des ObjectContext'es zurück und detached sie von ihrem Kontext.</summary>
public static Person GetFirstPerson()
{
using (FrankEntities fe = new FrankEntities())
{
var query = from p in fe.Person select p;
Person first = query.First();
fe.Detach(first); // p von ObjectContext 'fe' lösen.
return first;
}
}
/// <summary>Führt ein Update auf dem Server aus</summary>
public static void UpdatePerson(Person geändert, Person original)
{
using (FrankEntities fe = new FrankEntities())
{
fe.Attach(original);
fe.ApplyPropertyChanges(
original.EntityKey.EntitySetName, geändert);
fe.SaveChanges();
}
}
}
public static class Erweiterungen
{
/// <summary>Gibt das kopierte Objekt von 'person' zurück. Es werden nur öffentliche Properties kopiert.</summary>
public static Person Clone(this Person person)
{
Person newPerson = new Person();
PropertyInfo[] props = typeof(Person).
GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (PropertyInfo pi in props)
if (pi.Name != "EntityState" && pi.Name != "EntityKey")
pi.SetValue(newPerson, pi.GetValue(person, null), null);
return newPerson;
}
}
}