Entity Framework On-The-Fly serialization/encryption of properties - c#

Is that possible to serialize/deserialize a string property of an Entity by using its getters and setters on access, on save?
There are two main goals I would like to do for string properties.
1-Keep a json serialized string for special, complex or custom column types.
2-Encrypt on saving, decyrpt on access confidential information, i.e. Email address
Is that possible?
If so, do we have a limited usage of linq queries on this entity?
If so, would fetching all records and trigger their decryption/deserialization would work?

You could use the SavingChanges event to modify the entity right before saving it.
Then use the ObjectMaterialized event to handle when the properties are loaded into the entity.
Obviously, these events could be a little bit of overkill but I think you can have a lot of control and you may not want to attach event handlers every time you use the context.

Related

The optimal way to load referenced entities from other collections from C# and MongoDb

In my Mongo database I have two collections, let's they are A and B.
Entities of type A has, for example, a list of ids of entities of type B. This list is just a list of strings, where each string is a string representation of B's Id.
I want to reflect these reference relationships in my domain classes (and data classes at the same time) more clearly, so that I have a list of Bs inside of A, and would be able to query this list with possible filtering or ordering via LINQ.
Currently this is implemented in the following way:
I have a class MongoReference with a static event named 'MongoReferenceLoadRequested'. This event has event args that contain a type of referenced item and its id, also it has a read-write property of type Object, where the actual loaded object is supposed to be written to.
The event is fired whenever somebody wants to have an access to A's instance's list of Bs.
In my Global.asax.cs I subscribe to this event and in the handler load desired entity and assign it to event args' property. This is done to decouple application configuration, where MongoDb connection string is stored, and POCO entities classes, that do not have (and should not have) access to connection string.
How do you think, is this a correct way of achieving my goals?
Consider revisiting your document model in MongoDB. Sounds like a good candidate for having A have an array of B inside it in MongoDB.
// Document A:
{
_id: ... ,
values: [B1,B2,B3 ..]
}
This Impedance Mismatch is a legacy of RDBMS, and is due to implied relationships and the table-row kind of modeling and thinking.
See here for examples and discussion of appropriate data modeling in some common scenarios.

NHibernate instantiate collections on save

I am using NHibernate to persist my entities in the database. MY entities have some relationships between them resulting into some mapped collections. I my case I use the Iesi.ISet interface to map these collections. I was wondering if it's possible for nhibernate to check if the properties containing those collections to be automatically set when I execute save if they are null.
This is how it should work. I have a property with a collection called "MyCollection" that is null before I save it to the database. I want NHibernate to set a collection to that property so that it's not null anymore on save. Is this possible?
This is what your constructors are for.
If you very much want to hide such initialization behind NHibernate you might be able to inject the code for this using an NHibernate interceptor or event listener.

How are relational members from LINQ to SQL DataContext handled when objects are sent via WCF?

Let's say I have a relational database with tables: OrderableCategories and Orderables. They are in a relation of one-to-many with one OrderableCategory attached to multiple Orderables. Therefore, an OrderableCategory instance in LINQ has members: ID, Name and an EntitySet<Orderable> Orderables. While sent via WCF (wsHttpBinding if it matters anyhow), the EntitySet is translated to simple Orderable[]. An Orderable Instance also contains a member called OrderableCategory which is simply an instance of this orderable's category. While sent via WCF, I guess something like this happens: an Orderable instance fills its OrderableCategory instance with fields from this category, but its Orderable[] is also filled with other orderables in this category. These orderables have its OrderableCategory filled with this category again and so on, so that I could theoretically call (for a received orderable o): o.OrderableCategory.Orderables[0].OrderableCategory.Orderables[0]. (...) and so on. I'm only guessing that the server gets into an infinite loop and when message size exceeds the quota, it disconnects and I see an exception of service shutting down. How can I avoid this scenario and have the benefits of relations in my database? I think my suspicions are correct, because when I disabled one of the properties (made it internal in LINQ Class Designer), the data is filled "one-way" only and the Orderable has no longer its OrderableCategory member, it works. But I would like to know if this could be achieved without compromising the property.
This must be handled by marking entities with DataContract attribute and setting its IsReference property to true. This will instruct DataContractSerializer to track references instead of serialize objects as you descirbed.
Linq-To-Sql designer / SqlMetal should do this for you by setting Serialization Mode to Unidirectional.
If you send entities over WCF, nice features like lazy loading go out the window, of course.
You basically need to decide which of the two options you'd like to use:
if you ask for the entity OrderableCategory, you can return just its basic "atomic" properties, e.g. ID, Name and so on. The benefit is smaller size - you're sending back less data
or alternatively: if you ask for the entity OrderableCategory, you can return its basic properties plus you could load a whole list of Orderables that this category contains, and return both at the same time; benefit: you have that data available right away, but on the downside, you'll have to send a lot more data.
Obviously, you cannot really do an infinite eager pre-loading - at some point, you have to stop and leave retrieval of more data to a later WCF service call. Your client would have to ask specifically and explicitly for yet another OrderableCategory if you're interested in that.

How to manually override property OnLoad method in NHibernate?

Is it possible to manually change an entity when it's loaded from the database by NHibernate. Is there an OnLoad event listener which we can override or inherit from which will allow us to manually set an entity.
For clarity, we wish to assign a custom entity when the property is null. We are successfully doing the opposite when we persist to the database however would rather implement the logic in an NHibernate listener rather than in the property "Getter".
Please note we do not want to use IInterceptors as we are using the latest version of NHibernate.
You can implement IPostLoadEventListener. It's just one method:
void OnPostLoad(PostLoadEvent #event)
Which I think is exactly what you want.

LinqToSQL and auditing changed fields

Here's another one of these LinqToSQL questions where I'm sure I must have missed the boat somewhere, because the behavior of the O/R Designer is very puzzling to me...
I have a base class for my LinqToSQL tables, which I called LinqedTable. I've successfully used reflection to get hold of all the properties of the descendant classes and do other standard stuff.
Now I want to have some automatic auditing of my tables, so that whenever a LinqedTable record is inserted or deleted, or a field value changes, I will insert a record into an audit table, detailing the change type, the field name, and its value pre- and post-save.
I thought I would be able to do it using the PropertyChanging event, keeping track of all the changed properties before a save, then clearing the collection of changes after each SubmitChanges() call. But - the generated code from the O/R designer, for some bizarre reason, doesn't give you the property name in the PropertyChanging event - it sends an empty string! (WHY?!) It does send the property name in the PropertyChanged event, but that's already too late for me to get the original value.
I thought to grab all the original values of all properties using the OnLoaded() partial method - but that is private by definition, and I need access to that method in the base class. Even if I used reflection to get hold of that method, that would mean I would have to implement the other half of the partial method for every one of my tables, which kinda defeats the purpose of having inheritance!
I also can't find any suitable method in the DataContext to use or override.
So what would you recommend to get this audit functionality working?
You can use GetChangeSet on the DataContext to retrieve a list of updates, inserts and deletes that have occurred on all tables within a context. You can use ITable.GetOriginalEntityState to retrieve the original values of a changed entity. However, when you retrieve the original values of a deleted or updated record, the associations will not be available so you will have to rely on foreign key values only in that area if you need to process related entities. You can Use ITable.GetModifiedMembers to help retrieve only values that have changed.
Forgive me for perhaps a stupid answer, but how about doing the audit directly in the SQL Server using triggers (if you are in SQL Server 2005 or 2008 standard) or using the change tracking facilities in SQL server 2008 Enterprise?

Categories

Resources