How to audit using Entity Framework from Plugin - c#

I want to track the changes from plugin architecture. This is my code in plugin DbContext. I want to call this method if any changes occur in my whole application.
public override int SaveChanges()
{
this.Configuration.AutoDetectChangesEnabled = false;
this.Configuration.LazyLoadingEnabled = false;
this.Configuration.ProxyCreationEnabled = false;
var modifiedEntities = ChangeTracker.Entries()
.Where(e => e.State == EntityState.Added
|| e.State == EntityState.Modified
|| e.State == EntityState.Deleted).ToList();
foreach (var change in modifiedEntities)
{
var entityName = change.Entity.GetType().Name;
var primaryKey = GetPrimaryKeyValue(change);
List<Nop.Plugin.XcellenceIt.ChangeTracker.Domain.ChangeTracker> changeTrackerList = new List<Nop.Plugin.XcellenceIt.ChangeTracker.Domain.ChangeTracker>();
foreach (var prop in change.OriginalValues.PropertyNames)
{
var originalValue = change.OriginalValues[prop].ToString();
var currentValue = change.CurrentValues[prop].ToString();
if (originalValue != currentValue)
{
Nop.Plugin.XcellenceIt.ChangeTracker.Domain.ChangeTracker changeTracker = new Nop.Plugin.XcellenceIt.ChangeTracker.Domain.ChangeTracker()
{
EntityName = entityName,
PrimaryKeyValue = primaryKey.ToString(),
FieldName = prop,
OldValue = originalValue,
NewValue = currentValue,
EntityState = Convert.ToString(change.State),
DateChanged = DateTime.UtcNow
};
changeTrackerList.Add(changeTracker);
}
}
}
this.Configuration.AutoDetectChangesEnabled = true;
return base.SaveChanges();
}
I am unable to figure out this solution. Please help me.

Related

How do I add a JsonIgnore attribute to all properties with a specific return type in a class using Roslyn?

In the following code only one property is updated at a time and previously updated properties are ignored. I know that syntax nodes are immutable so I'm missing something. What I end up with is that only the last replaced property is updated. What am I missing?
var newMemberDeclarations = new SyntaxList<MemberDeclarationSyntax>();
newMemberDeclarations.AddRange(#class.Members);
foreach (var prop in props)
{
var oldProperty = (PropertyDeclarationSyntax)prop;
// e.g. Customer or ICollection<Customer>
if (oldProperty.Type.Kind() == SyntaxKind.IdentifierName ||
oldProperty.Type.Kind() == SyntaxKind.GenericName)
{
var memberAttributes = new SyntaxList<AttributeListSyntax>().AddRange(oldProperty.AttributeLists).Add(jsonIgnoreAttribute);
var newProperty = SyntaxFactory.PropertyDeclaration(
memberAttributes,
oldProperty.Modifiers,
oldProperty.Type,
oldProperty.ExplicitInterfaceSpecifier,
oldProperty.Identifier,
oldProperty.AccessorList
);
var replaced = #class.Members.Replace(oldProperty, newProperty);
// This ignores previously updated property
// and only adds the attribute on the last replaced property
newMemberDeclarations.AddRange(replaced);
}
}
var attributes = #class.AttributeLists.AddRange(attributeLists);
root = root.ReplaceNode(#class, #class.WithAttributeLists(attributes))
.AddUsings(usingSerialization, usingCollections, usingJson)
.WithMembers(newMemberDeclarations)
.NormalizeWhitespace();
foreach (var classDeclaration in classDeclarations)
{
var #class = classDeclaration as ClassDeclarationSyntax;
List<AttributeListSyntax> attributeLists = new List<AttributeListSyntax>();
attributeLists.Add(serializableAttribute);
var guidTypeSyntax = SyntaxFactory.ParseTypeName(typeof(Guid).FullName) as QualifiedNameSyntax;
var dateTimeTypeSyntax = SyntaxFactory.ParseTypeName(typeof(DateTime).FullName) as QualifiedNameSyntax;
var customTypes = #class.DescendantNodes().Where(x => x is PropertyDeclarationSyntax)
.Select(x => (PropertyDeclarationSyntax)x)
.Where(x => x.Type.Kind() == SyntaxKind.IdentifierName || x.Type.Kind() == SyntaxKind.GenericName)
;
customTypes.ToList().ForEach(t => // .Type.GetType().FullName
{
bool isGuid = ((IdentifierNameSyntax)t.Type).Identifier.Value == guidTypeSyntax.Right.Identifier.Value;
bool isDateTime = ((IdentifierNameSyntax)t.Type).Identifier.Value == dateTimeTypeSyntax.Right.Identifier.Value;
if (t.Type is GenericNameSyntax)
{
var args = ((GenericNameSyntax)t.Type).TypeArgumentList.Arguments;
foreach(var arg in args)
{
if(arg is IdentifierNameSyntax)
{
if (!(isGuid || isDateTime))
{
var type = ((IdentifierNameSyntax)arg).Identifier.Value.ToString();
var attribute = CreateKnownTypeAttribute(type);
var knownTypeEntityHashSetAttribute = CreateKnownTypeAttribute($"HashSet<{type}>");
attributeLists.Add(knownTypeEntityHashSetAttribute);
attributeLists.Add(attribute);
}
}
}
}
else if(t.Type is IdentifierNameSyntax)
{
if (!(isGuid || isDateTime))
{
var identifier = ((IdentifierNameSyntax)t.Type).Identifier.Value.ToString();
var attribute = CreateKnownTypeAttribute(identifier);
var knownTypeEntityHashSetAttribute = CreateKnownTypeAttribute($"HashSet<{identifier}>");
attributeLists.Add(knownTypeEntityHashSetAttribute);
attributeLists.Add(attribute);
}
}
});
var members = new SyntaxList<MemberDeclarationSyntax>(#class.Members);
customTypes.ToList().ForEach(oldProperty =>
{
var memberAttributes = new SyntaxList<AttributeListSyntax>().AddRange(oldProperty.AttributeLists).Add(jsonIgnoreAttribute);
var newProperty = SyntaxFactory.PropertyDeclaration(
memberAttributes,
oldProperty.Modifiers,
oldProperty.Type,
oldProperty.ExplicitInterfaceSpecifier,
oldProperty.Identifier,
oldProperty.AccessorList
) as MemberDeclarationSyntax;
if (oldProperty.Type is IdentifierNameSyntax)
{
bool isGuid = ((IdentifierNameSyntax)oldProperty.Type).Identifier.Value == guidTypeSyntax.Right.Identifier.Value;
bool isDateTime = ((IdentifierNameSyntax)oldProperty.Type).Identifier.Value == dateTimeTypeSyntax.Right.Identifier.Value;
bool isInt = oldProperty.Type.Kind() == SyntaxKind.IntKeyword;
bool isFloat = oldProperty.Type.Kind() == SyntaxKind.FloatKeyword;
if (!(isGuid || isDateTime))
{
var identifier = oldProperty.Identifier.Value;
var indexOf = members.IndexOf(m => m is PropertyDeclarationSyntax ? ((PropertyDeclarationSyntax)m).Identifier.Value == identifier : false);
members = members.RemoveAt(indexOf).Add(newProperty);
}
}
else if(oldProperty.Type is GenericNameSyntax)
{
var identifier = oldProperty.Identifier.Value;
var indexOf = members.IndexOf(m => m is PropertyDeclarationSyntax
? ((PropertyDeclarationSyntax)m).Identifier.Value == identifier : false);
members = members.RemoveAt(indexOf).Add(newProperty);
}
});
var attributes = #class.AttributeLists.AddRange(attributeLists);
var c = SyntaxFactory.ClassDeclaration(#class.Identifier)
.WithBaseList(#class.BaseList)
.AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword),
SyntaxFactory.Token(SyntaxKind.PartialKeyword))
.WithAttributeLists(attributes)
.AddMembers(members.ToArray());
root = root.ReplaceNode(#class, c)
.AddUsings(usingSerialization, usingCollections, usingSerialisation)
.NormalizeWhitespace();
}

How to add a Group of data with only one unique group ID using C# in MSSQL?

I want to create a group of registered clients using different products, categories and sub categories.
I am using asp.net C# and updating database using entity model.
int PID = Convert.ToInt32(ddProduct.SelectedValue);
if (isValidName(txtGroupName.Text))
{
if (ddBusinessCategory.SelectedValue == "0")
{
var clients = db.Client_Master.Where(c => c.InquiredFor == PID).ToList();
foreach (var clt in clients)
{
Group_Master gobj = new Group_Master();
gobj.GName = txtGroupName.Text;
gobj.ProductID = PID;
gobj.CatID = null;
gobj.SubCatID = null;
gobj.ClientID = clt.CID;
gobj.CreatedBy = Convert.ToInt32(((User_Master)Session["User"]).UID);
gobj.CreatedOn = DateTime.Now;
db.Group_Master.AddObject(gobj);
db.SaveChanges();
}
}
else
{
if (ddSubCategory.SelectedValue == "0")
{
int CID = Convert.ToInt32(ddBusinessCategory.SelectedValue);
var clients = db.Client_Master.Where(c => c.InquiredFor == PID && c.BusinessCategory == CID).ToList();
foreach (var clt in clients)
{
Group_Master gobj = new Group_Master();
gobj.GName = txtGroupName.Text;
gobj.ProductID = PID;
gobj.CatID = CID;
gobj.SubCatID = null;
gobj.ClientID = clt.CID;
gobj.CreatedBy = Convert.ToInt32(((User_Master)Session["User"]).UID);
gobj.CreatedOn = DateTime.Now;
db.Group_Master.AddObject(gobj);
db.SaveChanges();
}
}
else
{
int CID = Convert.ToInt32(ddBusinessCategory.SelectedValue);
int SID = Convert.ToInt32(ddSubCategory.SelectedValue);
var clients = db.Client_Master.Where(c => c.InquiredFor == PID && c.BusinessCategory == CID && c.SubCategory == SID).ToList();
foreach (var clt in clients)
{
Group_Master gobj = new Group_Master();
gobj.GName = txtGroupName.Text;
gobj.ProductID = PID;
gobj.CatID = CID;
gobj.SubCatID = SID;
gobj.ClientID = clt.CID;
gobj.CreatedBy = Convert.ToInt32(((User_Master)Session["User"]).UID);
gobj.CreatedOn = DateTime.Now;
db.Group_Master.AddObject(gobj);
db.SaveChanges();
}
}
}
Groups();
}
I tried to add Group ID using many ways but didn't succeed.
Please suggest me how can I solve this.
Thank you !!
You should create new table ClientsProducts, which will have reference to Client ID and Product ID. This is called One-to-Many Relationships.
You can read here about this here.
I Solved this by taking the ID of last data of list and save as a group ID so, with the help of this we get unique group ID.
if (ddBusinessCategory.SelectedValue == "0")
{
var clients = db.Client_Master.Where(c => c.InquiredFor == PID).ToList();
int GrpID = 0;
if (clients.Count() > 0)
{
foreach (var clt in clients)
{
if (ProductGrp(PID, clt.CID))
{
Group_Master gobj = new Group_Master();
gobj.GrpID = 0;
gobj.GName = txtGroupName.Text;
gobj.ProductID = PID;
gobj.CatID = null;
gobj.SubCatID = null;
gobj.ClientID = clt.CID;
gobj.CreatedBy = Convert.ToInt32(((User_Master)Session["User"]).UID);
gobj.CreatedOn = DateTime.Now;
db.Group_Master.AddObject(gobj);
db.SaveChanges();
GrpID = gobj.GID;
}
else
{
ScriptManager.RegisterStartupScript(Page, this.GetType(), "myscript()", "bootbox.alert({title: '<b>Error</b>',message: '<b>Group already exist.</b>',});", true);
break;
}
}
List<Group_Master> ggobj = db.Group_Master.Where(g => g.ProductID == PID && g.CatID == null && g.SubCatID == null).ToList();
foreach (var gid in ggobj)
{
if (gid.GrpID == 0)
{
Group_Master gmobj = db.Group_Master.Single(s => s.GID == gid.GID);
gmobj.GrpID = GrpID;
db.SaveChanges();
}
}
}
else
{
ScriptManager.RegisterStartupScript(Page, this.GetType(), "myscript()", "bootbox.alert({title: '<b>Error</b>',message: '<b>No Clients exist.</b>',});", true);
}
}

ChangeTracker.Entries() CurrentValue equals OriginalValue in EF7

I have a issue in EF7/asp.Net Core application. In my context I create a method Save:
public int Save()
{
ChangeTracker.DetectChanges();
var modifiedEntities = ChangeTracker.Entries()
.Where(p => p.State == EntityState.Modified || p.State == EntityState.Added || p.State == EntityState.Deleted || p.State == EntityState.Modified || p.State == EntityState.Detached).ToList();
var now = DateTime.UtcNow;
foreach (var change in modifiedEntities)
{
var entityName = change.Entity.GetType().Name;
var primaryKeyValue = GetPrimaryKeyValue(change.Entity);
foreach (var prop in change.Entity.GetType().GetTypeInfo().DeclaredProperties)
{
if (!prop.GetGetMethod().IsVirtual)
{
var currentValue = change.Property(prop.Name).CurrentValue;
var originalValue = change.Property(prop.Name).OriginalValue;
if (originalValue.ToString() != currentValue.ToString())
{
var changeLoged = new ChangeLog
{
PropertyName = prop.Name,
EntityName = entityName,
PrimaryKeyValue = primaryKeyValue,
DateChange = now,
OldValue = originalValue.ToString(),
NewValue = currentValue.ToString(),
ChangedBy = "test"
};
ChangeLog.Add(changeLoged);
}
}
}
}
return base.SaveChanges();
}
and method GetPrimaryKeyValue:
protected virtual int GetPrimaryKeyValue<T>(T entity)
{
var test = entity;
var test2 = test.GetType();
var keyName = this.Model.FindEntityType(test2).FindPrimaryKey().Properties
.Select(x => x.Name).Single();
var result = (int)entity.GetType().GetProperty(keyName).GetValue(entity, null);
if (result < 0)
return -1;
return result;
}
Unfortunatlly the change.Property(prop.Name).CurrentValue always equals OriginalValue, so the if
originalValue.ToString() != currentValue.ToString()
always return false.
Replace:
var originalValue = change.Property(prop.Name).OriginalValue;
to:
var originalValue = change.GetDatabaseValues().GetValue<object>(prop.Name);
This will not exactly answer your question since I cannot reproduce this issue but this may help you.
In EF Core, the PropertyEntry class has now an IsModified property which let you know if the value has been modified or not.
You should use it instead:
if (change.Property(prop.Name).IsModified)
{
var changeLoged = new ChangeLog
{
PropertyName = prop.Name,
EntityName = entityName,
PrimaryKeyValue = primaryKeyValue,
DateChange = now,
OldValue = originalValue.ToString(),
NewValue = currentValue.ToString(),
ChangedBy = "test"
};
ChangeLog.Add(changeLoged);
}
Disclaimer: I'm the owner of the project Entity Framework Plus
The Library has an Audit Feature (Supporting EF Core) which you may use or get inspired by to create your auditing (The code is Open Source).
Documentation: EF+ Audit
Based on the answers above I refactored my SetChanges method to this, and its working fine now! (EF 6 and .NET 6)
private void SetChanges()
{
TableName = Entry.Metadata.GetTableName();
var entsInDB = Entry.GetDatabaseValues();
foreach (PropertyEntry property in Entry.Properties)
{
if (property != null)
{
string propertyName = property.Metadata.Name;
if (property.Metadata.IsPrimaryKey())
{
KeyValues[propertyName] = property.CurrentValue ?? "";
continue;
}
switch (Entry.State)
{
case EntityState.Added:
NewValues[propertyName] = property.CurrentValue ?? "";
AuditType = AuditType.Create;
break;
case EntityState.Deleted:
OldValues[propertyName] = property.OriginalValue ?? "";
AuditType = AuditType.Delete;
break;
case EntityState.Modified:
if (property.IsModified)
{
var originalValue = entsInDB?.GetValue<object>(property.Metadata.Name);
if (originalValue?.ToString() != property.CurrentValue?.ToString())
{
ChangedColumns.Add(propertyName);
OldValues[propertyName] = originalValue?.ToString() ?? "";
NewValues[propertyName] = property.CurrentValue ?? "";
AuditType = AuditType.Update;
}
}
break;
}
}
}
}
Logging it to the database audit table:

Insert new rows based on date in Entity framework

I have been handed over an application that uses entity framework. I'm not familiar with entity and I'm having an issue that I can't figure out. This application was made to migrate data from a database to a more relational database. After the initial migration, we have to run it again to insert additional rows that were not part of the original migration. (There is a 3 week gap). I know that I have to put a check in and I want to do this by one of the columns we uses named "DateChanged" but unfortunately I'm not sure how to do this in entity. This is my first effort and it just shows in red which is depressing. I have searched on the internet but have found no solutions.
if (!newData.tVehicleLogs.Any(v => v.DateChanged.Value.ToShortDateString("6/27/2014")))//I'm not sure how to check the DateChanged here.
{
newData.tVehicleLogs.Add(deal);
comment = new tVehicleComment
{
Comment = vehicle.Reason,
DealID = deal.DealID,
CurrentComment = false
};
newData.tVehicleComments.Add(comment);
newData.SaveChanges();
int cId = comment.CommentID;
deal.CommentID = cId;
}
}
So as you can see I'm trying to check the date with the if statement, but I can't get the syntax correct... after trying everything I know to try .. which isn't much at this point.
I basically need to check if the DateChanged is from 6/27/2014 to today's date. If it's before then, then it has already been migrated over and doesn't need migrated over again. Where it says comment, if the row is new, then it inserts the old comment into the new comments table, then updates the tVehicleLogs table with the commentID. I'm just stuck on the date checking part. Any help is greatly appreciated!!
EDIT: This is the entire code for inserting the into tVehicleLogs..
if (MigrateLogs)
{
List<VLog> vlog = oldData.VLogs.ToList();
foreach (VLog vehicle in vlog)
{
tBank bank;
tCustomer cust;
tFIManager manag;
tSalesPerson sales;
tMake make;
tModel model;
tDealership dealership;
tMakeDealership makedeal;
tVehicleComment comment;
tInternalLocation location;
string dealershipName = getProperDealershipName(vehicle.Dealership, newData);
bank = (newData.tBanks.Any(banks => banks.BankName == vehicle.BankName) ? newData.tBanks.Where(b => b.BankName == vehicle.BankName).FirstOrDefault() : newData.tBanks.Add(new tBank { BankName = vehicle.BankName }));
cust = (newData.tCustomers.Any(customer => customer.CustomerNumber == vehicle.CustNumber) ? newData.tCustomers.Where(customer => customer.CustomerNumber == vehicle.CustNumber).FirstOrDefault() : newData.tCustomers.Add(new tCustomer { CustomerNumber = vehicle.CustNumber, CustomerName = vehicle.Buyer }));
//cust = (newData.tCustomers.Any(customer => customer.CustomerNumber == vehicle.CustNumber && customer.CustomerName == vehicle.CustNumber) ? newData.tCustomers.Where(customer => customer.CustomerNumber == vehicle.CustNumber).FirstOrDefault() : newData.tCustomers.Add(new tCustomer { CustomerNumber = vehicle.CustNumber, CustomerName = vehicle.Buyer }));
manag = (newData.tFIManagers.Any(manager => manager.FIName == vehicle.FIName) ? newData.tFIManagers.Where(manager => manager.FIName == vehicle.FIName).FirstOrDefault() : newData.tFIManagers.Add(new tFIManager { FIName = vehicle.FIName }));
sales = (newData.tSalesPersons.Any(person => person.SalesPersonNumber == vehicle.SalesPerson) ? newData.tSalesPersons.Where(person => person.SalesPersonNumber == vehicle.SalesPerson).FirstOrDefault() : newData.tSalesPersons.Add(new tSalesPerson { SalesPersonNumber = vehicle.SalesPerson }));
make = (newData.tMakes.Any(m => m.Make == vehicle.Make) ? newData.tMakes.Where(m => m.Make == vehicle.Make).FirstOrDefault() : newData.tMakes.Add(new tMake { Make = vehicle.Make }));
model = (newData.tModels.Any(m => m.Model == vehicle.Model) ? newData.tModels.Where(m => m.Model == vehicle.Model).FirstOrDefault() : newData.tModels.Add(new tModel { Model = vehicle.Model, MakeID = make.MakeID }));
dealership = (newData.tDealerships.Any(d => d.DealershipName == dealershipName) ? newData.tDealerships.Where(d => d.DealershipName == dealershipName).FirstOrDefault() : newData.tDealerships.Add(new tDealership { DealershipName = dealershipName }));
makedeal = (newData.tMakeDealerships.Any(d => d.MakeID == make.MakeID && d.DealershipID == dealership.DealershipID) ? newData.tMakeDealerships.Where(d => d.MakeID == make.MakeID && d.DealershipID == dealership.DealershipID).FirstOrDefault() : newData.tMakeDealerships.Add(new tMakeDealership { DealershipID = dealership.DealershipID, MakeID = make.MakeID }));
location = (newData.tInternalLocations.Any(l => l.LocationName == vehicle.Location) ? newData.tInternalLocations.Where(l => l.LocationName == vehicle.Location).FirstOrDefault() : newData.tInternalLocations.Add(new tInternalLocation { LocationName = vehicle.Location }));
//log = (newData.tVehicleLogs.Any(l => l.DealNumber == vehicle.FIMAST &&) ? newData.tVehicleLogs.Where(l => l.DealNumber == vehicle.FIMAST).FirstOrDefault() : newData.tVehicleLogs.Add(new tVehicleLog {DealNumber = vehicle.FIMAST }));
Int32 stat;
int? status;
if (Int32.TryParse(vehicle.Status, out stat))
status = stat;
else
status = null;
DateTime titled, bounced, dateReceived;
bool trueTitled = DateTime.TryParse(vehicle.Titled, out titled);
bool trueBounced = DateTime.TryParse(vehicle.Bounced, out bounced);
bool trueReceived = DateTime.TryParse(vehicle.DateReceived, out dateReceived);
int dealid = newData.tVehicleDeals.Where(v => v.DealNumber == vehicle.FIMAST).FirstOrDefault().DealID;
tVehicleLog deal = new tVehicleLog
{
DealNumber = vehicle.FIMAST,
StockNumber = vehicle.StockNumber,
BankID = bank.BankID,
CustomerID = cust.CustomerID,
FIManagerID = manag.FIManagerID,
SalesPersonID = sales.SalesPersonID,
VINNumber = null,
DealDate = vehicle.DealDate,
NewUsed = vehicle.NewUsed,
GrossProfit = vehicle.GrossProfit,
AmtFinanced = vehicle.AmtFinanced,
CloseDate = null,
Category = vehicle.RetailLease,
Status = status,
DealershipID = dealership.DealershipID,
NewDeal = false,
Archived = false,
InternalLocationID = location.InternalLocationID,
ChangedBy = vehicle.ChangedBy,
DateChanged = DateTime.Parse(vehicle.DateChanged),
Titled = null,
Bounced = null,
MakeID = make.MakeID,
ModelID = model.ModelID,
DealID = dealid,
CommentID = null
};
if (trueTitled)
deal.Titled = titled;
if (trueBounced)
deal.Bounced = bounced;
if (trueReceived)
deal.DateReceived = dateReceived;
DateTime targetDate = new DateTime(2014, 06, 27);
//if(!newData.tVehicleLogs.Any(v => v.DateChanged >= targetDate))
if(deal.DateChanged >= targetDate && !newData.tVehicleLogs.Any(v => v.DateChanged >= targetDate))
{
newData.tVehicleLogs.Add(deal);
comment = new tVehicleComment
{
Comment = vehicle.Reason,
DealID = deal.DealID,
CurrentComment = false
};
newData.tVehicleComments.Add(comment);
newData.SaveChanges();
int cId = comment.CommentID;
deal.CommentID = cId;
}
}
}
I don't think you need to use linq here (providing you've pulled the object down). Just check the dates.
// pull down the object
var deal = newData.tVehicleLogs.Where(v => v.Id == SOMEID).FirstOrDefault();
DateTime targetDate = new DateTime(2014,06,27);
if (tVehicleLogs.DateChaned <= DateTime.Now
&& tVehicleLogs.DateChaned >= targetDate) {
}
Alternatively, pull down all the objects that meet the date criteria and foreach over them.
List<YourObject> list = newData.tVehicleLogs.Where(v => v.DateChanged <= DateTime.Now
&& v.DateChanged >= targetDate).ToList();
foreach(var l in list) {
// do your stuff here
}

Writing to incidents in C#

I am using CRM 4 and the SDK to grab cases like so:
public List<Case> GetCases()
{
List<Case> cases = new List<Case>();
#region Retrieve Resolved Cases
try
{
InitSession();
RetrieveMultipleRequest req = new RetrieveMultipleRequest();
req.ReturnDynamicEntities = true;
//QueryExpression says what entity to retrieve from, what columns we want back and what criteria we use for selection
QueryExpression qe = new QueryExpression();
qe.EntityName = EntityName.incident.ToString();
List<string> attributes = new string[] {
"incidentid","title" ,"description", "ticketnumber", "statuscode",
"kez_allocatedhours",
"customerid",
"casetypecode"
}.ToList();
//columns to retireve
ColumnSet AvailabilityColumnSet = new ColumnSet();
AvailabilityColumnSet.Attributes = attributes.ToArray();
qe.ColumnSet = AvailabilityColumnSet;
//filter
FilterExpression fe = new FilterExpression();
fe.FilterOperator = LogicalOperator.And;
//condtion for filter
ConditionExpression isResolved = new ConditionExpression();
isResolved.AttributeName = "statuscode";
isResolved.Operator = ConditionOperator.NotEqual;
isResolved.Values = new string[] { "5" };
fe.Conditions = new ConditionExpression[] { isResolved }; //Add the conditions to the filter
qe.Criteria = fe; //Tell the query what our filters are
req.Query = qe; //Tell the request the query we want to use
//retrieve entities
RetrieveMultipleResponse resp = svc.Execute(req) as RetrieveMultipleResponse;
if (resp != null)
{
BusinessEntity[] rawResults = resp.BusinessEntityCollection.BusinessEntities;
List<DynamicEntity> castedResults = rawResults.Select(r => r as DynamicEntity).ToList();
foreach (DynamicEntity result in castedResults)
{
string id = GetProperty(result, "incidentid");
string title = GetProperty(result, "title");
string description = GetProperty(result, "description");
string ticket = GetProperty(result, "ticketnumber");
string customer = GetProperty(result, "customerid");
int statuscode = -1;
string statusname = "";
double estHours = 0.0;
string casetype = "";
int casetypecode = -1;
Property prop = result.Properties.Where(p => p.Name == "statuscode").FirstOrDefault();
if (prop != null)
{
StatusProperty status = prop as StatusProperty;
if (status != null)
{
statuscode = status.Value.Value;
statusname = status.Value.name;
}
}
prop = result.Properties.Where(p => p.Name == "kez_allocatedhours").FirstOrDefault();
if (prop != null)
{
CrmFloatProperty fl = prop as CrmFloatProperty;
if (fl != null)
{
estHours = fl.Value.Value;
}
}
prop = result.Properties.Where(p => p.Name == "casetypecode").FirstOrDefault();
if (prop != null)
{
PicklistProperty fl = prop as PicklistProperty;
if (fl != null)
{
casetype = fl.Value.name;
casetypecode = fl.Value.Value;
}
}
Case c = new Case();
c.ID = id;
c.Title = title;
c.Description = description;
c.StatusCode = statuscode;
c.StatusName = statusname;
c.TicketNumber = ticket;
c.CustomerName = customer;
c.EstimatedHours = estHours;
c.Type = casetype;
c.TypeCode = casetypecode;
bool allowedThroughStat = true;
bool allowedThroughType = true;
var userStatuses = SettingsManager.Get("CRMUserStatusReasons").Split(';').ToList().Where(p => p.Length > 0).ToList();
var userTypes = SettingsManager.Get("CRMUserCaseTypes").Split(';').ToList().Where(p => p.Length > 0).ToList();
if(userStatuses.Count > 0 && !userStatuses.Contains(c.StatusCode.ToString()))
{
allowedThroughStat = false;
}
if (userTypes.Count > 0 && !userTypes.Contains(c.TypeCode.ToString()))
{
allowedThroughType = false;
}
if(allowedThroughStat && allowedThroughType)
cases.Add(c);
}
}
}// end try
catch (Exception)
{
return null;
// The variable 'e' can access the exception's information.
// return "Error Message: " + e.Message.ToString() + " | Stack Trace: " + e.StackTrace.ToString();
}
return cases;
#endregion
}
However, now I need to be able to change the status and title of a case from C# given its incidentid.
Ive looked at the SDK docs and cannot find an example of this.
Anyone work with this before?
Thanks
Simply put, above is code to read an incident. Could I get an example of writing an incident field, Just one. Ex: How could I change the title of an incident.
You can call the Update method on the CrmService. Here is the SDK article.
Case c = new Case();
c.ID = id;
c.Title = title;
svc.Update(c);
To change the state of an entity you use the setstaterequest. If you want to do it to a dynamic entity there's a description in this blog

Categories

Resources