Audit.EntityFramework.Core 16.2.1 not tracking Foreign Object changes - audit.net

In POST request we sent a payload with its Foreign object data and audit GetEntityFrameworkEvent() show correct values.
But when we make a PUT request then Audit.EntityFramework.Core 16.2.1 does not track Foreign Object changes i.e Changes Array Field has same values in every New and Old fields.

That coould be because of the nature of the update operation.
If you don't explicitly retrieve the object before the update, there is no way for the EF ChangeTracker to know the previous values.
Please check https://github.com/thepirat000/Audit.NET/issues/53

Related

Marketo REST API - what is "dedupeFields" for custom objects?

When it comes to creating/updating custom objects, can I use both dedupeFields or lookupField when pushing the data to Marketo?
What is the difference between the two?
I'm not sure what do you mean under lookupField, as there is no such input field described in the API documentation of the Sync Custom Objects endpoint. (That is the endpoint to create or update custom objects.)
In the other hand, you do not need such a standalone lookup field, as with the input array you provide the objects you want to create or update, with all their important values. Have a look at the sample payload in the docs.
When input is used together with the optional dedupeBy and action fields, you have full control over which object you want to create or update.
Also, the endpoint expects the name of the dedupe field under dedupeBy key, as opposed to dedupeFields. So the name is singular; you can provide a single field name use, and it does what you can expect: if the value in the field for a given record is not unique, an error will be returned for the individual record.

How to entirely skip validation in simple schema and allow incomplete documents to be stored?

I'm creating an order form and a schema defined for an Order (certain required fields such as address, customer info, items selected and their quantities, etc).
a. User visits site.
b. A unique ID is generated for their session as well as a timestamp.
var userSession = {
_id: createId(),
timestamp: new Date(),
};
var sessionId = userSession._id;
c. The userSession is placed in local storage.
storeInLocalStorage('blahblah', sessionObject);
d. An Order object is created with the sessionId as the only field so far.
var newOrder = {
sessionId: sessionId;
};
e. Obviously at this point the Order object won't validate according to the schema so I can't store it in Mongo. BUT I still want to store it in Mongo so I can later retrieve incomplete orders, or orders in progress, using the sessionID generated on the user's initial visit.
This won't work because it fails validation:
Orders.insert(newOrder);
f. When a user revisits the site I want to be able to get the incomplete order from Mongo and resume:
var sessionId = getLocalStorage('blahblah')._id;
var incompleteOrder = Orders.findOne({'sessionId', sessionId});
So I'm not sure how to go about doing this while accomplishing these points.
I want full simpleschema validation on the Orders collection when the user is entering in items on the forms and when the user is intending to submit a full, complete order.
I want to disable simpleschema validation on the Orders collection and still allow storing into the DB so that partial orders can be stored for resumption at a later time.
I can make a field conditionally required using this here but that would mean 50+ fields would be conditionally required just for this scenario and that seems super cumbersome.
It sounds like you want to have your cake, and eat it too!
I think the best approach here would be keep your schema and validation on the Orders collection, but store incomplete orders elsewhere.
You could store them in another collection (with a more relaxed schema) if you want them on the server (possibly for enabling resume on another device for the logged in user) , or more simply in Local Storage, and still enable the resume previous order behaviour you are wanting.
Only write to the Orders collection when the order is complete (and passes validation).
Here's a variation on #JeremyK's answer: add an inProgress key to your order of type [Object]. This object would have no deeper validation. Keep your in progress order data in there until the order is final then copy/move all the relevant data into the permanent keys and remove the inProgress key. This would require that you make all the real keys optional of course. The advantage is that the object would maintain its primary key throughout the life cycle.
I think this particular case has been solved; but just in case, you can skip Simple Schemma validations by accessing MongoDB native API via Collection#rawCollection():
Orders.rawCollection().insert(newOrder);
While this question is very old in the meantime there is a better solution. You probably use simple schema together with collection2. Collection2 has the ability to set multiple schemas based on a selector and then validate against the correct schema based on it.
https://github.com/Meteor-Community-Packages/meteor-collection2#attaching-multiple-schemas-to-the-same-collection
e.g. you could have a selector {state: 'finished'} and only apply the full schema to these documents while having another selctor, e.g. {state: 'in-progress'} for unfinished orders with a schema with optional fields.

Is there a way to use the DBC views to find the last date and time that a database schema was altered?

I would like to find the date and time that any schema modification has taken place on a particular database. Modifications are things like tables or columns that have been created, altered, or dropped. It does not include any data that has been inserted, updated, or deleted.
The reason why I need this is because I am writing a .NET utility that depends heavily on the data returned from dbc.tables, dbc.columns, and dbc.indices. Since querying these views can be a very expensive operation, I want to read it all into custom business objects and then serialize the objects to an XML file stored on disk. This way, I can just deserialize the data when I need it unless the database's current_timestamp is greater than or equal to the datetime of the last schema change, at which point I'll refresh the local XML file with the updated schema.
LastAlterTimestamp - If it is equal to CreateTimestamp then object has not been modified since being created or replaced. It is updated when an attribute specific to that data dictionary object was updated.
For example, DBC.Databases.LastAlterTimestamp is not update when a child object (table, view, macro, stored procedure, function, etc.) is added, removed, or altered. It is updated in situations such as when the password, default role, profile, or account is changed.

Concurrency when deleting object in Entity Framework

I'm developing a web app using the entity framework. I load a list of objects and bind it to a repeater to show a summary of all the items. The user may click an edit icon or a delete icon for each item in the repeater.
Example:
Item 1 | Edit | Delete
Item 2 | Edit | Delete
...
Editing works fine when using a rowversion column for concurrency because the record is loaded and the values for the ID and rowversion column are persisted in hidden form fields. These "original" values are then available to use later when doing the update.
However, if the user clicks Delete for a record, I load the object from the database, call DeleteObject(), then call SaveChanges(). The problem with this is that when I load the record, it gets the latest rowversion value, so any concurrency checking is rendered useless.
How can I ensure that concurrency checking takes place when deleting a record?
Actually you do not have to load the object from the database, if you want to delete it.
Instead, create an ObjectContext, attach your ObjectToDelete to that context via Attach(), then DeleteObject() and SaveChanges().
Thus you would be able to receive an exception about concurrency.
After reading the answer to this question, I decided to use the following approach.
Use hidden form fields to store the ID and rowversion value.
When the user clicks the delete button, load the object from the database. This object contains a rowversion value that may be different than what is stored in the hidden field.
Assign the rowversion value from the hidden field to the appropriate property
on the object.
Call the object state manager's AcceptChanges() method for this object. This causes the rowversion value that I had stored to be accepted as the "current" value.
Delete the object and call SaveChanges() on the object context.
Therefore, the original rowversion value I stored is passed to SQL when attempting to delete the record and is compared to the current value in the row. If they do not match, an OptimisticConcurrencyException is raised.
A different approach than Andreas H specified would be to use stored procedures to do your deletes. That way you could do concurrency checking and deletion within the stored proc, raising an exception if there is a violation.

How to create a new record with a particular GUID

Using the Dynamics CRM I'm trying to create an instance of an entity. I would like to manually set the GUID, but if I had the attribute that is the primary key to the DynamicEntity, I get following error.
Service could not process request
I am building a DynamicEntity, and setting the [entityname]id attribute causes the request to fail. It's moving data between two CRM instances, so if anyone knows of a better way to copy records between CRMs, that'd work too. Otherwise, I'd like the GUID to match across instances... as that's the point of a GUID.
Happily, it IS possible to do this across two CRM instances! A co-worker knew the solution, so credit really belongs to him.
My mistake was creating a Property with type UniqueIdentifierProperty. The primary key attribute on an entity needs to be filled in with a KeyProperty. These two properties are nearly identical -- the Property types are, except that one holds a Key, the other a UniqueIdentifier. The Key/UniqueIdentifier both hold GUIDs. (Another day in the mind of Microsoft!)
Precisely, what I'm doing is creating a DynamicEntity, filling in the entity name, and filling in the majority of the attributes. The PK attribute (which you can determine from the metadata) can be filled in with a KeyProperty. I was filling it in with a UniqueIdentifierProperty, which CRM rejects and responds with a nondescript and unhelpful error message.
I apologize if I am over-simplifying the solution, but why not add a custom field in both instances that would be a mirror of the other instances guid?

Resources