[CSHARP-769] Option, attribute, or convention to suppress discriminator in certain classes Created: 30/Jun/13  Updated: 19/Oct/16  Resolved: 02/Jul/13

Status: Closed
Project: C# Driver
Component/s: None
Affects Version/s: 1.6
Fix Version/s: None

Type: Improvement Priority: Minor - P4
Reporter: Curt Mayers Assignee: Sridhar Nanjundeswaran
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

All



 Description   

It would be useful to have a way to suppress the discriminator for certain classes.

In my case, all classes that are to be stored in Mongo are descended from an abstract class that "knows" how to store things to Mongo:

It will store to a collection name based on the actual class name
It knows how to maintain housekeeping fields like CreateDate, LastUpdateDate, _id generation, and self-Archival and numbering of archive versions.

These are quite useful in this particular project, and it would be pretty painful to have to implement for each class to be saved to the database (there are currently about 14).

Because all the business objects are derived from this abstract class, the driver adds a discriminator to each record when it is serialized. This is quite unnecessary, since each actual class is saved to a separate collection.

Can an option be added to the serializer or ClassMap classes, or conventions or attributes, that would allow suppression of these discriminators? Or is there a way of doing that already?

I already tried defining a ShouldSerialzet or ShouldSerialize_t method in the base class, but that doesn't seem to do it.



 Comments   
Comment by Sridhar Nanjundeswaran [ 02/Jul/13 ]

From an offline exchange: if you want to be able to store one or more subtypes but do not need the discriminator stored as each subtype is stored in a different collection, you could do something like:

var actualType = (objToBePersisted == null) ? typeof(BaseClass) : objToBePersisted.GetType();
var nominalType = actualType;
var result = collToBeSavedIn.Save(nominalType, objToBePersisted);

Comment by Curt Mayers [ 02/Jul/13 ]

Here's the actual abstract class I'm using, at this point (see attachment).
All classes which are saved to Mongo descend from it.
To get to the "interesting" parts, search for "##############"

I'm sorry if this has too much specific in it, but I thought it would be
more useful to send you the actual class

Here're the behaviors the class implements:

1. It tracks a record version ID which is incremented on each DB
save.

2. When a record is updated, a new Archive record is also created
and written to an Archival DB.
The _id of the regular record is an incrementing unsigned
integer, created with a generator.
The _id of the Archival record, on the other hand, is a
calculated compounding of the
regular record's id, plus the incrementing version ID.

3. Provenance information (record creation and update dates, and
persons) are automatically added to the record
at the time of db save.

4. There're two virtual methods to return a collection name: one
for regular records, and one for
archival records. Unless overwritten in a descendant class,
they return the class name,
or the class name + "Archive".

5, Records are saved to a collection name specified by the two
methods described above,
so record types within collections are actually homogeneous (if
a descendant class decides
to store heterogeneous record types in a single collection, it
must implement its own
selector.

There are (currently) 14 classes, all of which descend from this abstract
class: each is stored into
a different collection. Thus there is no need for a discriminator in each
db record: they are superfluous
and a waste of disk and memory space.

I added three sample classes at the bottom of the source file to
illustrate. Each of these knows how to store itself,
keeps provenance information, and keeps a complete archive of all versions
(these are all requirements for the project
I'm working on). All of this behavior is interited from the abstract
base class. (BTW: it is not a mature class yet:
I'm quite sure more base functionality will be added.)

I would just like a way (perhaps a class attribute) which would allow me to
suppress the expression
of the discriminator. Perhaps something like:

[BsonSuppressDiscriminator(true)]

In the meantime, I'd like to know if there is a way to accomplish this
through a policy, or a ShouldSerialize function,
or any other means like that.

Does this all make sense to you?

(BTW: please don't post the source file to a public place, it would be a
violation of my contract).

Thanks,
Curt

On Mon, Jul 1, 2013 at 5:37 PM, Sridhar Nanjundeswaran (JIRA) <

Comment by Sridhar Nanjundeswaran [ 02/Jul/13 ]

Hi Curt,
Do you have some sample code you could show to illustrate the behavior you expect? I added a simple example to show when and where the discriminator gets written https://gist.github.com/sridharn/2c915ba58c6faecc714b. I apologize if you have already experimented with this.

Comment by Curt Mayers [ 01/Jul/13 ]

I don't think you understood the question. Since I'm using an abstract base class to do the mongo access, and record housekeeping, the nominal and actual classes are ALWAYS different. Since this base class stores different record types into different collections, there is no need for a discriminator.

Comment by Sridhar Nanjundeswaran [ 01/Jul/13 ]

The driver only adds the discriminator when the actual type and the nominal type are different. If they are the same then it does not add the discriminator. Hence you should be able to suppress the _t field by having the actual and nominal types as the same

Generated at Wed Feb 07 21:37:46 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.