Мы рассматриваем использование ServiceStack.OrmLite.SqlServer 4.0.31, подключенного к MSSQL 2008R2, чтобы заменить наш текущий ORM и испытываем трудности с настройкой сериализации сложного типа. В нашем старом ORM это были сопоставления вручную с использованием auto mapper для строковых полей с использованием JSON.NET, поэтому у нас уже есть JSON в базе данных в столбцах, которые являются VARCHAR (MAX).
Я установил строковый сериализатор:
SqlServerDialect.Provider.StringSerializer = new JsonDataContractSerializer();
Тип базы данных:
public class Group
{
[Alias("GroupID")]
[AutoIncrement]
[PrimaryKey]
public int GroupId { get; set; }
[Alias("Name")]
public string Name { get; set; }
[Alias("ShortName")]
public string ShortName { get; set; }
[Alias("GroupTypeID")]
public int GroupTypeId { get; set; }
[Alias("ContactDetails")]
public ContactDetails ContactDetails { get; set; }
}
Контактная информация:
[DataContract]
[Serializable]
public class ContactDetails
{
[DataMember]
public string FirstName { get; set; }
[DataMember]
public string LastName { get; set; }
[DataMember]
public string CompanyName { get; set; }
[DataMember]
public string Title { get; set; }
[DataMember]
public string Address { get; set; }
}
Объект создается, но ни одно из полей не сериализуется:
Данные в базе данных следующие:
{
"Address" : "2 Doe Street, Dublin 2",
"Phone" : "01 4684455",
"PhoneIsVerified" : false,
"MobileIsVerified" : false,
"Fax" : "01 4684455",
"Email" : "[email protected]",
"Website" : "http://www.doe.ie",
"PropertySectionEmail" : {},
"IsPrivate" : false
}
Данные в БД выглядят так:
Я видел в github, что поле по умолчанию для хранения для этих полей было VARBINARY (MAX), поэтому я не уверен, что почему он не работает, но я проверил все атрибуты в аннотациях данных, и не было никого, что я мог видеть, чтобы указать, что это был сложным типом. Любые идеи, почему это не работает?
В конце концов я нашел проблему в своем коде. Я использовал:
SqlServerDialect.Provider.StringSerializer = new JsonDataContractSerializer();
OrmLiteConfig.DialectProvider = SqlServerDialect.Provider;
OrmLiteConnectionFactory(connectionString, new SqlServerOrmLiteDialectProvider());
Где я должен был использовать:
SqlServerDialect.Provider.StringSerializer = new JsonDataContractSerializer();
OrmLiteConfig.DialectProvider = SqlServerDialect.Provider;
OrmLiteConnectionFactory(connectionString, SqlServerDialect.Provider);
Поэтому я создал пустого поставщика диалектов, у которого не было привязанного сериализатора.
Я не уверен, что вы ошибаетесь, но я просто попробовал ваш пример и работает так, как ожидалось:
SqlServerDialect.Provider.StringSerializer = new JsonDataContractSerializer();
var db = OpenDbConnection();
db.DropAndCreateTable<Group>();
Будет генерировать схему ниже:
DROP TABLE "Group"
CREATE TABLE "Group"
(
"GroupID" INTEGER PRIMARY KEY IDENTITY(1,1),
"Name" VARCHAR(8000) NULL,
"ShortName" VARCHAR(8000) NULL,
"GroupTypeID" INTEGER NOT NULL,
"ContactDetails" VARCHAR(MAX) NULL
);
Что мы теперь можем вставлять и выбирать из без проблем:
var group = new Group
{
Name = "Group Name",
ShortName = "GN",
GroupTypeId = 1,
ContactDetails = new ContactDetails {
Address = "Address",
CompanyName = "Company",
FirstName = "First",
LastName = "Last",
Title = "Title",
}
};
db.Save(group);
var result = db.SingleById<Group>(group.GroupId);
result.PrintDump();
Это отображает заполненную строку, как ожидалось:
{
GroupId: 1,
Name: Group Name,
ShortName: GN,
GroupTypeId: 1,
ContactDetails:
{
FirstName: First,
LastName: Last,
CompanyName: Company,
Title: Title,
Address: Address
}
}
И внутри SQL Server он хранит JSON, как ожидалось:
Этот пример также доступен как автономный тест.