"/", , , , , .
, Entity Framework (STE). EF STE , , , PropertyChanged, , "".
, / - ViewModels , , . (DAL vs M vs VM vs V). , MVVM .
:
- . , "", , , "" () . " ".
- MVVM, , , . - .
- "", , .
- , "".
- .
- , .
, :
-, Car, . , Dirty.
public class Car : IEquatable<Car>, ICloneable
{
public string Make { get; set; }
public string Model { get; set; }
public bool Equals(Car other)
{
return other.Make == this.Make &&
other.Model == this.Model;
}
public object Clone()
{
return new Car { Make = this.Make, Model = this.Model };
}
}
, CarRepository, :
public class CarRepository
{
private ChangeTracker<Car> _cars = new ChangeTracker<Car>();
public IEnumerable<Car> GetCars()
{
int dbId1 = 1;
string make1 = "Ford";
string model1 = "Focus";
Car car1;
if (!_cars.IsTracking(dbId1))
car1 = new Car();
else
car1 = _cars.GetItem(dbId1);
car1.Make = make1;
car1.Model = model1;
if (!_cars.IsTracking(dbId1))
_cars.StartTracking(dbId1, car1);
return _cars.GetTrackedItems();
}
public void SaveCars(IEnumerable<Car> cars)
{
foreach (var changedItem in _cars.GetChangedItems().Intersect(cars))
{
}
foreach (var newItem in cars.Except(_cars.GetTrackedItems()))
{
int newId = 5;
_cars.StartTracking(newId, newItem);
}
_cars.SetNewCheckpoint();
}
}
, , ChangeTracker.
public class ChangeTracker<T> where T : IEquatable<T>, ICloneable
{
private Dictionary<int, T> _originals = new Dictionary<int, T>();
private Dictionary<T, int> _originalIndex = new Dictionary<T, int>();
private Dictionary<int, T> _copies = new Dictionary<int, T>();
private Dictionary<T, int> _copyIndex = new Dictionary<T, int>();
public bool IsChanged(T copy)
{
var original = _originals[_copyIndex[copy]];
return original.Equals(copy);
}
public IEnumerable<T> GetChangedItems()
{
return _copies.Values.Where(c => IsChanged(c));
}
public IEnumerable<T> GetTrackedItems()
{
return _copies.Values;
}
public void SetNewCheckpoint()
{
foreach (var copy in this.GetChangedItems().ToList())
{
int dbId = _copyIndex[copy];
var oldOriginal = _originals[dbId];
var newOriginal = (T)copy.Clone();
_originals[dbId] = newOriginal;
_originalIndex.Remove(oldOriginal);
_originalIndex.Add(newOriginal, dbId);
}
}
public void StartTracking(int dbId, T item)
{
var newOriginal = (T)item.Clone();
_originals[dbId] = newOriginal;
_originalIndex[newOriginal] = dbId;
_copies[dbId] = item;
_copyIndex[item] = dbId;
}
public void StopTracking(int dbId)
{
var original = _originals[dbId];
var copy = _copies[dbId];
_copies.Remove(dbId);
_originals.Remove(dbId);
_copyIndex.Remove(copy);
_originalIndex.Remove(original);
}
public bool IsTracking(int dbId)
{
return _originals.ContainsKey(dbId);
}
public bool IsTracking(T item)
{
return _copyIndex.ContainsKey(item);
}
public T GetItem(int dbId)
{
return _liveCopies[dbId];
}
}
:
static void Main(string[] args)
{
var repository = new CarRepository();
var cars = repository.GetCars().ToArray();
cars[0].Make = "Chevy";
cars[1].Model = "Van";
repository.SaveCars(cars);
}
IEquatable ICloneable, , , , , , -, , . (, ). , .