Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在SQLlite中将列映射到DateTime属性时,如何忽略字符串空值?_C#_Entity Framework_Sqlite_Datetime - Fatal编程技术网

C# 在SQLlite中将列映射到DateTime属性时,如何忽略字符串空值?

C# 在SQLlite中将列映射到DateTime属性时,如何忽略字符串空值?,c#,entity-framework,sqlite,datetime,C#,Entity Framework,Sqlite,Datetime,我使用实体框架从C#控制台应用程序读取SQLite数据库 问题是:我有许多列包含空字符串(例如:“”),并且映射到C#中的DateTime属性 当我试图读取这些记录时,这里是我得到的错误: 最内层异常System.FormatException:字符串“”为 无法识别为有效的日期时间。在 System.DateTimeParse.Parse(只读span`1 s,DateTimeFormatInfo dtfi, DateTimeStyles(样式)位于 Microsoft.Data.Sqlite

我使用实体框架从C#控制台应用程序读取SQLite数据库

问题是:我有许多列包含空字符串(例如:“”),并且映射到C#中的DateTime属性

当我试图读取这些记录时,这里是我得到的错误:

最内层异常System.FormatException:字符串“”为 无法识别为有效的日期时间。在 System.DateTimeParse.Parse(只读span`1 s,DateTimeFormatInfo dtfi, DateTimeStyles(样式)位于 Microsoft.Data.Sqlite.SqliteValueReader.GetDateTime(Int32序号)

将列映射到可为空的DateTime并不能解决此问题

显而易见的解决方案是清除所有这些空字符串,并用空值替换它们。在我的例子中,这不是小事,我不能保证将来不会有任何其他字符串空值

令人惊讶的是,如果映射到整数的列包含空字符串值,则该列可以工作(值映射到“0”)

在映射到DateTime时,有没有办法忽略这些空字符串值?(例如:它将返回空日期或DateTime.MinValue)。注意:我使用ISO 8601格式,而不是刻度

编辑: 这是我的密码

public class FooContext : DbContext
{
    protected override void OnConfiguring(DbContextOptionsBuilder builder) {     
           builder.UseSqlite("Data Source=Database.db");
    }

    public DbSet<Bar> Bar { get; set; }
}

public class Bar
{
    public int ID { get; set; }
    public DateTime? SomeDate { get; set; }
}

using(FooContext context = new FooContext())
{                
    var bar = context.Find<Bar>(id); //throw exception
} 
公共类FooContext:DbContext
{
配置时受保护的覆盖无效(DbContextOptionsBuilder){
builder.UseSqlite(“数据源=Database.db”);
}
公共DbSet条{get;set;}
}
公共类酒吧
{
公共int ID{get;set;}
公共日期时间?SomeDate{get;set;}
}
使用(FooContext=newfoocontext())
{                
var bar=context.Find(id);//抛出异常
} 

您可能必须在上下文类的
OnModelCreating
方法上处理此问题。实际上,您必须重写此方法。在此方法中,我们创建了一个转换器,用于转换从数据库中读取的属性
SomeDate
的值:

public class FooContext : DbContext
{
    protected override void OnConfiguring(DbContextOptionsBuilder builder) {     
           builder.UseSqlite("Data Source=Database.db");
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        DateTime parsedDateTime;
        var converter = new ValueConverter<string, DateTime?>(
            v => string.IsNullOrWhiteSpace(v)
                ? null
                : DateTime.TryParse(v, out parsedDateTime)
                    ? parsedDateTime
                    : (DateTime?) null,
            v => v != null
                ? v.ToString()
                : string.Empty);

        modelBuilder
           .Entity<Bar>()
           .Property(b=>b.SomeDate)
           .HasConversion(converter);
    }    

    public DbSet<Bar> Bar { get; set; }
}
公共类FooContext:DbContext
{
配置时受保护的覆盖无效(DbContextOptionsBuilder){
builder.UseSqlite(“数据源=Database.db”);
}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
日期时间解析数据时间;
var转换器=新值转换器(
v=>string.IsNullOrWhiteSpace(v)
无效的
:DateTime.TryParse(v,out-parsedDateTime)
?解析时间
:(日期时间?)空,
v=>v!=null
?v.ToString()
:string.Empty);
建模者
.实体()
.Property(b=>b.SomeDate)
.转换(转换器);
}    
公共DbSet条{get;set;}
}

您可以阅读更多关于值转换的内容。

您可能必须在上下文类的
OnModelCreating
方法中处理此问题。实际上,您必须重写此方法。在此方法中,我们创建了一个转换器,用于转换从数据库中读取的属性
SomeDate
的值:

public class FooContext : DbContext
{
    protected override void OnConfiguring(DbContextOptionsBuilder builder) {     
           builder.UseSqlite("Data Source=Database.db");
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        DateTime parsedDateTime;
        var converter = new ValueConverter<string, DateTime?>(
            v => string.IsNullOrWhiteSpace(v)
                ? null
                : DateTime.TryParse(v, out parsedDateTime)
                    ? parsedDateTime
                    : (DateTime?) null,
            v => v != null
                ? v.ToString()
                : string.Empty);

        modelBuilder
           .Entity<Bar>()
           .Property(b=>b.SomeDate)
           .HasConversion(converter);
    }    

    public DbSet<Bar> Bar { get; set; }
}
公共类FooContext:DbContext
{
配置时受保护的覆盖无效(DbContextOptionsBuilder){
builder.UseSqlite(“数据源=Database.db”);
}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
日期时间解析数据时间;
var转换器=新值转换器(
v=>string.IsNullOrWhiteSpace(v)
无效的
:DateTime.TryParse(v,out-parsedDateTime)
?解析时间
:(日期时间?)空,
v=>v!=null
?v.ToString()
:string.Empty);
建模者
.实体()
.Property(b=>b.SomeDate)
.转换(转换器);
}    
公共DbSet条{get;set;}
}

您可以阅读有关值转换的更多信息。

请输入您用于读取所述记录的代码,好吗?感谢您编辑了问题您使用的是哪一版本的EF?@Aldert我使用的是Microsoft.EntityFrameworkCore.Sqlite 2.1您能用代码阅读您提到的记录吗?谢谢您编辑了问题您使用的是哪个版本的EF?@Aldert我使用的是Microsoft.EntityFrameworkCore.Sqlite 2.1有没有办法为所有日期时间字段设置名为的转换器?(因此我不必硬编码所有表的所有可能字段的hascoveration()调用)。我知道我可以通过思考来做到这一点,但也许有更好的方法。@tigrou我不知道有这样的事情。我也搜索了一下,什么也没找到。但是,与使用反射相比,使用EFCore提供的API显式声明更好。是否有方法为所有日期时间字段设置调用的转换器?(因此我不必硬编码所有表的所有可能字段的hascoveration()调用)。我知道我可以通过思考来做到这一点,但也许有更好的方法。@tigrou我不知道有这样的事情。我也搜索了一下,什么也没找到。但是,IMHO最好使用EFCore提供的API显式声明,而不是使用反射。