This question is locked. New answers and comments are not allowed.
I am trying to get a type converter to work but the app is complaining that the converter cannot be found. I created a FluentAPI project and added a converter there by following this FluentAPI blog post and this type converters Blog post. I basically have two classes: Book and Identifier and if I don't have a type converter everything seems to be fine. I am trying to convert date/time to a text representation which is how the date/time is stored in SQLite database:
Again, the class is in the FluentAPI project and here is the PrepareMapping method:
The error I am getting is this: Could not load type 'Data.SqliteDateToDateTime' from assembly 'Telerik.OpenAccess.Runtime, Version=2011.2.713.3, Culture=neutral, PublicKeyToken=7ce17eeaf1d59342'.":"Data.SqliteDateToDateTime"} System.Exception {System.TypeLoadException}.
Any help is appreciated.
public
class
SqliteDateToDateTime : AdoTypeConverter
{
private
bool
nullable;
public
override
AdoTypeConverter Initialize(IDataColumn user, Type clr,
IAdoTypeConverterRegistry registry,
bool
secondaryTable)
{
//first we need to ensure that the clr type can be handled by this converter
if
(clr ==
typeof
(DateTime) && user.ResolvedSqlType ==
"varchar"
)
{
//then we need to set a flag to determine if the type is nullable
nullable =
typeof
(DateTime?) == clr;
//finally return base.Initialize, which ultimatly returns "this"
return
base
.Initialize(user, clr, registry, secondaryTable);
}
//if the converter can not work with the specified clr type we return null
return
null
;
}
public
override
object
Read(
ref
DataHolder holder)
{
//check if the value is dbnull
bool
isNull = holder.Reader.IsDBNull(holder.Position);
//set wheather or not there is a value
holder.NoValue = isNull;
//if the value is null, then we need to return default values
if
(isNull)
{
//if the type is nullable, and the value is null, we simply return null
if
(nullable)
holder.ObjectValue =
null
;
//if the value is null, and we need to box it, we set the objectvalue to 0
else
if
(holder.Box)
holder.ObjectValue = 0;
else
//other wise the value is null, so we simply return the default int value
holder.Int32Value = 0;
}
else
{
//the value is not null, so here we want to pull the value out, and convert it to a string
DateTime dt;
string
s = holder.Reader.GetValue(holder.Position).ToString();
int
index = s.IndexOf(
"+"
);
if
(index >= 0)
{
dt = DateTime.Parse(s.Substring(0, s.IndexOf(
"+"
)));
}
else
{
dt = DateTime.Parse(s);
}
//if the value is nullabel, or needs to be boxed, we set the ObjectValue Property of the DataHolder
if
(nullable || holder.Box)
holder.ObjectValue = dt;
else
//otherwise we can set the Int32Value property to the parseed int value
holder.DateTimeValue = dt;
}
//now we return our value
return
holder.ObjectValue;
// (holder.Box || nullable) ? holder.ObjectValue : null;
}
public
override
void
Write(
ref
DataHolder holder)
{
//set the db type
holder.Parameter.DbType = System.Data.DbType.String;
//if there is no value we could specify what to set the db field to
if
(holder.NoValue)
{
//in this case we just want to set it to null
holder.Parameter.Value =
null
;
}
else
{
//When there is a value we simply need to take our CLR int, and convert it to a string
//and then set the parameter info
string
s = holder.DateTimeValue.ToString(
"yyyy-MM-dd HH:mm:ss+00:00"
);
holder.Parameter.Size = s.Length;
holder.Parameter.Value = s;
}
}
public
override
bool
CreateLiteralSql(
ref
DataHolder holder)
{
//If there is no value, then we just want to query against null.
if
(holder.NoValue)
{
holder.StringValue =
"NULL"
;
//returning false indicates that no quotes are required. We want NULL instead of 'NULL'
return
false
;
}
else
{
//convert the int value into a string, since that is what we are storing it as in the db
holder.StringValue = holder.DateTimeValue.ToString(
"yyyy-MM-dd HH:mm:ss+00:00"
);
// return true indicates that quotes are needed around the value
return
true
;
}
}
public
override
Type DefaultType
{
get
{
return
typeof
(DateTime); }
}
}
Again, the class is in the FluentAPI project and here is the PrepareMapping method:
protected
override
IList<MappingConfiguration> PrepareMapping()
{
List<MappingConfiguration> configurations =
new
List<MappingConfiguration>();
MappingConfiguration<Book> bookConfiguration =
new
MappingConfiguration<Book>();
bookConfiguration.MapType(p =>
new
{
id = p.Id,
title = p.Title
}).ToTable(
"books"
);
bookConfiguration.HasProperty(x => x.PublishedDate)
.ToColumn(
"pubdate"
)
.HasColumnType(
"text"
)
.WithConverter<SqliteDateToDateTime>();
bookConfiguration.HasProperty(p => p.Id).IsIdentity();
MappingConfiguration<Identifier> identifierConfiguration =
new
MappingConfiguration<Identifier>();
identifierConfiguration.MapType(p =>
new
{
id = p.Id,
book = p.BookId,
type = p.Type,
val = p.Value
}).ToTable(
"identifiers"
);
identifierConfiguration.HasProperty(p => p.Id).IsIdentity();
identifierConfiguration.HasAssociation(p => p.Book).WithOpposite(c => c.Identifiers).HasConstraint((p, c) => p.BookId == c.Id);
configurations.Add(bookConfiguration);
configurations.Add(identifierConfiguration);
return
configurations;
}
The error I am getting is this: Could not load type 'Data.SqliteDateToDateTime' from assembly 'Telerik.OpenAccess.Runtime, Version=2011.2.713.3, Culture=neutral, PublicKeyToken=7ce17eeaf1d59342'.":"Data.SqliteDateToDateTime"} System.Exception {System.TypeLoadException}.
Any help is appreciated.