EnVisageOnline/Beta/Source/EnVisage/EnVisageEntities.cs

239 lines
10 KiB
C#

namespace EnVisage
{
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Core.Objects;
using System.Data.Entity.Core.Objects.DataClasses;
using System.Data.Entity.Infrastructure;
using System.IO;
using System.Reflection;
using System.Runtime.Serialization;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;
using System.Linq;
using System.Data.Entity.Core;
using NLog;
using Microsoft.AspNet.Identity;
using System.Web;
public partial class EnVisageEntities : DbContext
{
public ObjectContext ObjectContext()
{
return (this as IObjectContextAdapter).ObjectContext;
}
List<History> historyList = new List<History>();
//partial void OnContextCreated()
//{
// this.ObjectContext().SavingChanges += new EventHandler(projectionsEntities_SavingChanges);
//}
public override int SaveChanges()
{
historyList.Clear();
List<ObjectStateEntry> changes = this.ObjectContext().ObjectStateManager.GetObjectStateEntries(EntityState.Modified).ToList();
changes.AddRange(this.ObjectContext().ObjectStateManager.GetObjectStateEntries(EntityState.Added).ToList());
changes.AddRange(this.ObjectContext().ObjectStateManager.GetObjectStateEntries(EntityState.Deleted).ToList());
foreach (ObjectStateEntry stateEntryEntity in changes)
{
if (!stateEntryEntity.IsRelationship &&
stateEntryEntity.Entity != null &&
!(stateEntryEntity.Entity is History) &&
(
stateEntryEntity.Entity is Project ||
stateEntryEntity.Entity is Scenario ||
stateEntryEntity.Entity is AspNetUser ||
stateEntryEntity.Entity is AspNetRole ||
stateEntryEntity.Entity is ProjectAccess ||
stateEntryEntity.Entity is Security ||
stateEntryEntity.Entity is Expenditure ||
stateEntryEntity.Entity is ExpenditureCategory ||
stateEntryEntity.Entity is Expenditure2Expenditure ||
stateEntryEntity.Entity is FeeCalculation ||
stateEntryEntity.Entity is Rate ||
stateEntryEntity.Entity is Company ||
stateEntryEntity.Entity is Client ||
stateEntryEntity.Entity is UOM ||
stateEntryEntity.Entity is EnVisage.Type ||
stateEntryEntity.Entity is EnVisage.Status ||
stateEntryEntity.Entity is FiscalCalendar ||
stateEntryEntity.Entity is GLAccount ||
stateEntryEntity.Entity is ScenarioDetail ||
stateEntryEntity.Entity is Company2Client ||
stateEntryEntity.Entity is Company2View
)
)
{//is a normal entry, not a relationship
History history = this.HistoryFactory(stateEntryEntity);
historyList.Add(history);
}
}
if (historyList.Count > 0)
{
List<Guid> ids = new List<Guid>();
foreach (var history in historyList)
{
if (!ids.Contains(history.Id))
{
ids.Add(history.Id);
this.Histories.Add(history);
}
else
{
history.Id = Guid.NewGuid();
if (!ids.Contains(history.Id))
this.Histories.Add(history);
}
}
}
return base.SaveChanges();
}
private History HistoryFactory(ObjectStateEntry entry)
{
History history = new History();
var objectStateEntry = this.ObjectContext().ObjectStateManager.GetObjectStateEntry(entry.Entity);
history.Id = Guid.NewGuid();
if (entry.State != EntityState.Added)
history.EntityId = new Guid(objectStateEntry.EntityKey.EntityKeyValues[0].Value.ToString());
history.TimeStamp = DateTime.Now;
try
{
history.ModifiedBy = new Guid(HttpContext.Current.User.Identity.GetUserId());
}
catch(Exception)
{
history.ModifiedBy = Guid.Empty;
}
history.ModificationType = entry.State.ToString();
history.EntityType = entry.Entity.GetType().Name.Split('_')[0];
history.XML = GetEntryValueInString(entry, true);
return history;
}
private string GetEntryValueInString(ObjectStateEntry entry, bool isOrginal)
{
XmlDocument doc = new XmlDocument();
XmlElement el = (XmlElement)doc.AppendChild(doc.CreateElement("Entity"));
XmlElement modified = null;
el.SetAttribute("type", entry.Entity.GetType().Name.Split('_')[0]);
var props = entry.Entity.GetType().GetProperties();
if (entry.State == EntityState.Modified || entry.State == EntityState.Deleted)
foreach (var elem in props)
{
var name = elem.Name;
int i = -1;
try { i = entry.OriginalValues.GetOrdinal(elem.Name); }
catch { }
if (i >= 0)
{
var val = Convert.ToString(entry.OriginalValues[entry.OriginalValues.GetOrdinal(elem.Name)]);
el.AppendChild(doc.CreateElement(name)).InnerText = Convert.ToString(val);
if (entry.State == EntityState.Modified && val != Convert.ToString(elem.GetValue(entry.Entity)))
{
if (modified == null) modified = (XmlElement)el.AppendChild(doc.CreateElement("Modified"));
modified.AppendChild(doc.CreateElement(name)).InnerText = Convert.ToString(elem.GetValue(entry.Entity));
}
}
}
if (entry.State == EntityState.Added)
foreach (var elem in props)
{
if (elem.Name == "Id")
{
var val = elem.GetValue(entry.Entity);
el.AppendChild(doc.CreateElement(elem.Name)).InnerText = Convert.ToString(val);
}
}
return doc.OuterXml;
}
public EntityObject CloneEntity(EntityObject obj)
{
DataContractSerializer dcSer = new DataContractSerializer(obj.GetType());
MemoryStream memoryStream = new MemoryStream();
dcSer.WriteObject(memoryStream, obj);
memoryStream.Position = 0;
EntityObject newObject = (EntityObject)dcSer.ReadObject(memoryStream);
return newObject;
}
public List<History> GetHistory(Guid Id)
{
return (from s in this.Histories where (s.EntityId == Id) select s).ToList();
}
public void RecoverFromHistory(Guid HistoryId)
{
var history = (from s in this.Histories where (s.Id == HistoryId) select s).FirstOrDefault();
object recovered = GetEntityFromXML(history.XML, "Show");
EditEntity(this, (EntityObject)recovered);
}
public static object GetEntityFromXML(string ObjectInXML, string typeName)
{
XDocument doc = XDocument.Parse(ObjectInXML);
var type = doc.Root.Attribute("type").Value;
var id = new Guid(doc.Root.Element("Id").Value);
System.Type entityType = System.Type.GetType(type);
var entity = Activator.CreateInstance(entityType);
var props = entityType.GetProperties();
foreach (var prop in props)
{
if (prop.Name == "Modified") continue;
var name = prop.Name;
var val = doc.Root.Element(name).Value;
if (null != prop && prop.CanWrite) prop.SetValue(entity, val, null);
}
return entity;
}
public static void EditEntity(EnVisageEntities context, EntityObject entity)
{
// Define an ObjectStateEntry and EntityKey for the current object.
EntityKey key;
object originalItem;
// Get the detached object's entity key.
if (entity.EntityKey == null)
{
// Get the entity key of the updated object.
key = context.ObjectContext().CreateEntityKey(entity.GetType().Name, entity);
}
else
{
key = entity.EntityKey;
}
try
{
// Get the original item based on the entity key from the context
// or from the database.
if (context.ObjectContext().TryGetObjectByKey(key, out originalItem))
{//accept the changed property
// Call the ApplyPropertyChanges method to apply changes
// from the updated item to the original version.
context.ObjectContext().ApplyCurrentValues(key.EntitySetName, entity);
}
else
{
context.ObjectContext().AddObject(entity.GetType().Name, entity);
}
}
catch (Exception ex)
{
var sb = DateTime.Now.ToString() + ": " + ex.Message;
var logger = LogManager.GetCurrentClassLogger();
if (logger != null)
logger.Fatal(sb.ToString());
}
}
}
}