sql >> Databasteknik >  >> NoSQL >> MongoDB

MongoDB C# drivrutinstyp diskriminatorer med generisk klass som ärver från icke-generisk basklass

Efter lite experimenterande fick jag reda på att man kan skriva sina egna diskrimineringskonventioner. Jag kan inte riktigt förstå varför, men standarddiskriminatorkonventionen verkar använda egenskapen Name för typklassen istället för FullName, vilket gör den värdelös för generiska klasser.

Det slutade med att jag använde den här koden istället:

class FooDiscriminatorConvention : IDiscriminatorConvention
{
    public string ElementName
    {
        get { return "_t"; }
    }

    public Type GetActualType(MongoDB.Bson.IO.BsonReader bsonReader, Type nominalType)
    {
        if(nominalType!=typeof(MyAbstractClass))
            throw new Exception("Cannot use FooDiscriminator for type " + nominalType);

        var ret = nominalType;

        var bookmark = bsonReader.GetBookmark();
        bsonReader.ReadStartDocument();
        if (bsonReader.FindElement(ElementName))
        {
            var value = bsonReader.ReadString();

            ret = Type.GetType(value);

            if(ret==null)
                throw new Exception("Could not find type " + value);

            if(!ret.IsSubclassOf(typeof(MyAbstractClass)))
                throw new Exception("Database type does not inherit from MyAbstractClass.");
        }

        bsonReader.ReturnToBookmark(bookmark);

        return ret;
    }

    public BsonValue GetDiscriminator(Type nominalType, Type actualType)
    {
        if (nominalType != typeof(MyAbstractClass))
            throw new Exception("Cannot use FooDiscriminator for type " + nominalType);

        return actualType.FullName;
    }
}

Och registrera den med

BsonSerializer.RegisterDiscriminatorConvention(typeof(MyGenericClass<>), new FooDiscriminatorConvention()); //is this needed?
BsonSerializer.RegisterDiscriminatorConvention(typeof(MyAbstractClass), new FooDiscriminatorConvention());

Jag var också tvungen att göra basklassen icke-abstrakt för att undvika felet "kan inte skapa instanser av abstrakta klasser". Det skulle vara trevligt att kunna ha en abstrakt basklass, men eftersom den härledda klassen är generisk kan jag inte använda BsonKnownTypes.



  1. Få det högsta värdet av en kolumn i MongoDB

  2. Många-till-många-kartläggning med Mongoose

  3. Vad är det korrekta sättet att indexera i MongoDB när stora kombinationer av fält finns

  4. Snabbreferensguide till olika NoSQL-databaser