简体   繁体   English

如果我创建了一个隐式类型转换运算符,我可以让Raven DB序列化一个对象,因为它会成为一个字符串吗?

[英]Can I make Raven DB serialize an object as it would a string, if i have created an implicit type conversion operator?

I have a class that looks something like this: 我有一个看起来像这样的类:

public class MyClass
{
    string _value;

    public static implicit operator MyClass (string value)
    {
        return new MyClass(value);
    }

    MyClass(string value)
    {
        // Do something...
        _value = value;
    }

    public override string ToString()
    {
         // Do something...
         return _value;
    }
}

Hence, I can use the class like this: 因此,我可以使用这样的类:

MyClass a = "Hello!";

But in Raven DB it will just be stored like 但是在Raven DB中它只会被存储起来

"SomeProperty": {}

since it has no public properties. 因为它没有公共财产。 And it is quite useless. 而且它毫无用处。

To solve this I would make the _value private member a public property instead, like this: 要解决这个问题,我会将_value私有成员改为公共属性,如下所示:

public string Value { get; set; }

and Raven DB will store 和Raven DB将存储

"SomeProperty": { "Value": "Hello!" }

and it will be deserializable. 它将是可反序列化的。

But I don't want this public property. 但我不想要这个公共财产。 Can I somehow make Raven DB serialize and deserialize the class as was it would a string? 我可以以某种方式使Raven DB序列化和反序列化类,就像它是一个字符串? Like: 喜欢:

"SomeProperty": "Hello!"

Hi I know this is old but I thought I would add some additions to Ayendes' reply to help people who like me had the same issue and spent hours looking on forums for an answer (of which there were a few but none had any example that you could follow), it's not hard to figure this out but with an example I could have solved this in 10 minutes as opposed to spending a few hours. 嗨,我知道这已经老了,但我想我会在Ayendes的回复中添加一些补充,以帮助那些喜欢我的人有同样的问题,并花了几个小时在论坛上寻找答案(其中有一些但没有任何例子,你可以遵循),不难想象这一点,但有一个例子我可以在10分钟内解决这个问题而不是花费几个小时。

My problems was that we have custom value type structs in our application the example I will use is EmailAddress. 我的问题是我们的应用程序中有自定义值类型结构,我将使用的示例是EmailAddress。 Unfortunately in Ravendb we could not run queries against these types without defining a custom serialiser. 不幸的是,在Ravendb中,如果没有定义自定义序列化器,我们无法对这些类型运行查询。

Our Value Type looked Like this: 我们的价值类型看起来像这样:

[DataContract(Namespace = DataContractNamespaces.ValueTypes)]
public struct EmailAddress : IEquatable<EmailAddress>
{
    private const char At = '@';

    public EmailAddress(string value) : this()
    {
        if (value == null)
        {
            throw new ArgumentNullException("value");
        }

        this.Value = value;
    }

    public bool IsWellFormed
    {
        get
        {
            return Regex.IsMatch(this.Value, @"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*");
        }
    }

    public string Domain
    {
        get
        {
            return this.Value.Split(At)[1];
        }
    }

    [DataMember(Name = "Value")]
    private string Value { get; set; }

    public static bool operator ==(EmailAddress left, EmailAddress right)
    {
        return left.Equals(right);
    }

    public static bool operator !=(EmailAddress left, EmailAddress right)
    {
        return !left.Equals(right);
    }

    public override bool Equals(object obj)
    {
        if (obj == null)
        {
            return false;
        }

        return this.Equals(new EmailAddress(obj.ToString()));
    }

    public override int GetHashCode()
    {
        return this.Value.GetHashCode();
    }

    public override string ToString()
    {
        return this.Value;
    }

    public bool Equals(EmailAddress other)
    {
        return other != null && this.Value.Equals(other.ToString(), StringComparison.OrdinalIgnoreCase);
    }
}

The type of document we wanted to save and query would look something like this 我们想要保存和查询的文档类型看起来像这样

public class Customer
{
    public Guid Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public EmailAddress Email { get; set; }
}

The custom serialiser to store our email as a raw string and then convert it back to its value type on retrieval looked like this: 自定义序列化程序将我们的电子邮件存储为原始字符串,然后在检索时将其转换回其值类型,如下所示:

public class EmailConverterTest : JsonConverter
{

    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(EmailAddress);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        EmailAddress actualAddress =  new EmailAddress(reader.Value.ToString());

        return actualAddress;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        EmailAddress actualAddress = (EmailAddress)value;
        string stringEmail = actualAddress.ToString();
        writer.WriteValue(stringEmail);
    }
}

Finally I wired it up and was able to query everything as follows: 最后我把它连接起来,并能够查询所有内容,如下所示:

    public static void serializercustom(Newtonsoft.Json.JsonSerializer serialiser)
    {
        serialiser.Converters.Add(new EmailConverterTest());
    }

    public static void TestCustomer()
    {
        using (var documentStore = new DefaultDocumentStore())
        {
            documentStore.ConnectionStringName = Properties.Settings.Default.SandBoxConnection;
            documentStore.Initialize();
            documentStore.Conventions.CustomizeJsonSerializer = new Action<Newtonsoft.Json.JsonSerializer>(serializercustom);

            var customer = new Customer
            {
                Id = Guid.NewGuid(),
                FirstName = "TestFirstName",
                LastName = "TestLastName",
                Email = new EmailAddress("testemail@gmail.com")
            };

            // Save and retrieve the data
            using (var session = documentStore.OpenSession())
            {
                session.Store(customer);
                session.SaveChanges();
            }

            using (var session = documentStore.OpenSession())
            {
                var addressToQuery = customer.Email;
                var result = session.Query<Customer>(typeof(CustomerEmailIndex).Name).Customize(p => p.WaitForNonStaleResults()).Where(p => p.Email == addressToQuery);

                Console.WriteLine("Number of Results {0}", result.Count()); // This always seems to return the matching document
            }
        }
    } 

You can write a JsonConverter and teach RavenDB how you want to store the data. 您可以编写JsonConverter并教您如何存储数据的RavenDB。 After you write the converter, register it in the store.Conventions.CustomizeSerializer event. 编写转换器后,将其注册到store.Conventions.CustomizeSerializer事件中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 C#:如何在 object 期间使用隐式转换运算符进行类型转换? - C#: How can I use implicit cast operator during object to type conversion? 我可以通过运算符重载来进行隐式转换吗? - Can I make this implicit conversion from an operator overload work? 如何使DataContractJsonSerializer将对象序列化为字符串? - How can I make DataContractJsonSerializer serialize an object as a string? ArgumentException: 无法转换类型的对象。 但我有一个隐式运算符 C# - ArgumentException: Object of type cannot be converted. But I have an implicit operator C# 我可以序列化C#Type对象吗? - Can I serialize a C# Type object? 我可以在C#中实现从字符串到布尔值的隐式“转换”吗? - Can I implement an implicit 'conversion' from string to boolean in C#? 我可以让 .NET 使用 object 类型到 JSON 序列化多态 ZA2F2ED4F8EBC2CBB16C21A29DC40 吗? - Can I make .NET use the object type to JSON serialize a polymorphic class? 为什么即使创建了显式运算符,我也无法将源类型转换为字符串? - Why I can't convert source type to string even though explicit operator is created? 我该如何进行隐式转换? - How can i do the implicit conversion? 我有一个将原始类型拆箱到对象的方法。我想让它成为性能的通用方法,并使它看起来更干净 - I have a method that is unboxing primitive type to object .I would like to make it a generic method for performance and make it look more cleaner
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM