// --- Wiederverwendbarer Teil --------------
public enum DetachedEntityState
{
New, Updated, Deleted, Unchanged
}
public interface IEntity
{
DetachedEntityState State { get; set; }
}
public static class StateTrackingHelper
{
public static void ApplyStates<T>(this ICollection<T> entities, DbContext ctx) where T : class, IEntity
{
foreach (var e in entities)
{
ApplyState(e, ctx);
}
}
public static void ApplyState<T>(this T entity, DbContext ctx) where T : class, IEntity
{
switch (entity.State)
{
case DetachedEntityState.New:
ctx.Entry<T>(entity).State = System.Data.EntityState.Added;
break;
case DetachedEntityState.Updated:
ctx.Entry<T>(entity).State = System.Data.EntityState.Modified;
break;
case DetachedEntityState.Deleted:
ctx.Entry<T>(entity).State = System.Data.EntityState.Deleted;
break;
}
}
public static ICollection<T> ResetStates<T>(this ICollection<T> entities) where T : class, IEntity
{
foreach (var e in entities)
{
ResetState(e);
}
return entities;
}
public static void ResetState<T>(this T entity) where T : class, IEntity
{
entity.State = DetachedEntityState.Unchanged;
}
}
// --- Anwendung --------------
public class Region: IEntity
{
public Region()
{
Hotels = new List<Hotel>();
Top10Hotels = new List<Hotel>();
}
private int _RegionId;
public int RegionId
{
get
{
return _RegionId;
}
set
{
if (_RegionId != value) {
_RegionId = value;
this.State = DetachedEntityState.Updated;
}
}
}
private string _Bezeichnung;
public string Bezeichnung
{
get
{
return _Bezeichnung;
}
set
{
if (_Bezeichnung != value) {
_Bezeichnung = value;
this.State = DetachedEntityState.Updated;
}
}
}
private ICollection<Hotel> _Hotels;
public virtual ICollection<Hotel> Hotels
{
get
{
return _Hotels;
}
set
{
if (_Hotels != value) {
_Hotels = value;
this.State = DetachedEntityState.Updated;
}
}
}
private ICollection<Hotel> _Top10Hotels;
public virtual ICollection<Hotel> Top10Hotels
{
get
{
return _Top10Hotels;
}
set
{
if (_Top10Hotels != value) {
_Top10Hotels = value;
this.State = DetachedEntityState.Updated;
}
}
}
private DetachedEntityState _State;
[NotMapped]
public DetachedEntityState State
{
get
{
return _State;
}
set
{
_State = value;
}
}
}
public class Hotel : IEntity
{
private int _HotelId;
public int HotelId
{
get
{
return _HotelId;
}
set
{
if (_HotelId != value) {
_HotelId = value;
this.State = DetachedEntityState.Updated;
}
}
}
private string _Bezeichnung;
public string Bezeichnung
{
get
{
return _Bezeichnung;
}
set
{
if (_Bezeichnung != value) {
_Bezeichnung = value;
this.State = DetachedEntityState.Updated;
}
}
}
private int _Sterne;
public int Sterne
{
get
{
return _Sterne;
}
set
{
if (_Sterne != value) {
_Sterne = value;
this.State = DetachedEntityState.Updated;
}
}
}
private int _RegionId;
public int RegionId
{
get
{
return _RegionId;
}
set
{
if (_RegionId != value) {
_RegionId = value;
this.State = DetachedEntityState.Updated;
}
}
}
private Region _Region;
[ForeignKey("RegionId"), InverseProperty("Hotels")]
public virtual Region Region
{
get
{
return _Region;
}
set
{
if (_Region != value) {
_Region = value;
this.State = DetachedEntityState.Updated;
}
}
}
private DetachedEntityState _State;
[NotMapped]
public DetachedEntityState State
{
get
{
return _State;
}
set
{
_State = value;
}
}
}
public class WellnessHotel : Hotel
{
private int _AnzahlSaunen;
public int AnzahlSaunen
{
get
{
return _AnzahlSaunen;
}
set
{
if (_AnzahlSaunen != value) {
_AnzahlSaunen = value;
this.State = DetachedEntityState.Updated;
}
}
}
private int _AnzahlThermalBecken;
public int AnzahlThermalBecken
{
get
{
return _AnzahlThermalBecken;
}
set
{
if (_AnzahlThermalBecken != value) {
_AnzahlThermalBecken = value;
this.State = DetachedEntityState.Updated;
}
}
}
}
public class HotelDbContext : DbContext
{
public HotelDbContext(): base("CodeOnlyHotelDb") { }
public DbSet<Hotel> Hotels { get; set; }
public DbSet<Region> Regionen { get; set; }
}
public class RegionDAO
{
public List<Region> FindAll()
{
using (var ctx = new HotelDbContext())
{
var result = ctx.Regionen.Include("Hotels").ToList();
result.ResetStates();
return result;
}
}
public void UpdateRegion(Region r)
{
using (var ctx = new HotelDbContext())
{
ctx.Regionen.Attach(r);
r.ApplyState(ctx);
r.Hotels.ApplyStates(ctx);
ctx.SaveChanges();
r.ResetState();
r.Hotels.ResetStates();
}
}
public void SaveRegion(Region r1)
{
using (var ctx = new HotelDbContext())
{
ctx.Regionen.Add(r1);
ctx.SaveChanges();
}
}
}
class Program
{
static void Main(string[] args)
{
Database.SetInitializer(new DropCreateDatabaseAlways<HotelDbContext>());
CreateSaveModifySaveDemo();
LoadShowModifySaveDemo();
LoadShowModifySaveDemo();
Console.WriteLine("fertig!");
Console.ReadLine();
}
private static void CreateSaveModifySaveDemo()
{
var dao = new RegionDAO();
Region r1 = new Region { Bezeichnung = "Graz" };
Hotel h1 = new Hotel { Bezeichnung = "Hotel zur Post", Sterne = 2 };
WellnessHotel h2 = new WellnessHotel
{
Bezeichnung = "Hotel zur Wellness",
Sterne = 4,
AnzahlSaunen = 3,
AnzahlThermalBecken = 4
};
r1.Hotels.Add(h1);
r1.Hotels.Add(h2);
r1.Top10Hotels.Add(h2);
dao.SaveRegion(r1);
h2.Sterne++;
r1.Bezeichnung += "!"; // kleine Änderung
dao.UpdateRegion(r1);
}
private static void LoadShowModifySaveDemo()
{
var dao = new RegionDAO();
var regionen = dao.FindAll();
foreach (var r in regionen)
{
Console.WriteLine(r.Bezeichnung);
r.Bezeichnung += "$"; // kleine Änderung
int i = 0;
foreach (var h in r.Hotels)
{
Console.WriteLine(" " + h.Bezeichnung + ", Sterne: " + h.Sterne);
if (i++ % 2 == 0) h.Bezeichnung += "$"; // kleine Änderung
}
Console.WriteLine();
dao.UpdateRegion(r);
}
}
}