【问题标题】:Zumero Sqlite Sql Server Data Class Invalid CastZumero Sqlite Sql Server 数据类无效转换
【发布时间】:2020-02-05 14:56:53
【问题描述】:

我和我的团队正在 Xamarin Forms 中构建一个移动应用程序,以允许我们的客户通过移动设备对他们的数据进行一些基本的访问。我们正在使用 zumero 来处理创建 ms sql server 数据库的本地 sqlite 副本。为了让 Entity Framework Core 在设备上工作,我通过对 zumero 同步的 sqlite 文件进行逆向工程来创建模型和上下文。

public partial class tblEmployeeSchedule : BaseModel, ICrewMember
{
    //...
    public string DtDate { get; set; }
public class EFDatabase : IDataStore
{
    public DataContext Context { get; set; }
    public EFDatabase(string filepath)
    {
        try
        {
            this.Context = new DataContext(filepath);
public partial class DataContext : DbContext
{
    public string ConnString { get; private set; }

    public DataContext(string filepath)
    {
        this.ConnString = filepath;
    }

    //...
    public virtual DbSet<tblEmployeeSchedule> tblEmployeeSchedule { get; set; }
    //...

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        //...
        modelBuilder.Entity<tblEmployeeSchedule>(entity =>
        {
            entity.HasKey(e => e.Oid);

            entity.Property(e => e.DtDate).HasColumnName("dt_date");
        //...

对于下一阶段的开发,我在 Visual Studio 解决方案中添加了一个 WinForms 项目,并尝试创建一个与移动应用程序具有相似功能的非常简单的应用程序,并且我希望能够在可能的情况下重用数据模型.

一开始,我误以为我可以简单地覆盖一行代码:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder.UseSqlite($"Data Source={ConnString}");

用这个替换它:

protected override void OnConfiguring(DbContextOptionsBuilder options)
    => options.UseSqlServer(ConnString);
var connString = $"Server={server}; Database={db}; User Id={username}; Password={password};";
Program.Database = new SqlServerDatabase(connString);

但是当我尝试运行该程序时,它抛出了以下错误:

InvalidCastException
Message: "Specified cast is not valid."
Source: "Microsoft.Data.SqlClient"

我猜测错误来自数据模型不匹配。当 Zumero 通过信息同步时,它在 SQLite 文件中创建了 text 类型的列。我尝试使用直接从 SQL Server 逆向工程的数据模型,并使用它创建 SQLite 文件,列类型为datetime

我还尝试使用 SQL Server 逆向工程师提供的protected override void OnModelCreating(ModelBuilder modelBuilder),并给出以下错误消息:"The property 'tblCrewSchedule.DtDate' is of type 'string' which is not supported by current database provider. Either change the property CLR type or ignore the property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'."

我一直在想办法构建一个双方都可以使用的代码优先数据模型,但我想不出一个解决方案。我想也许如果 Zumero 知道一种方法,我可以在 C# 中创建一个属性为 DateTime 类型的模型,即使 Zumero 正在创建一个 text 类型的 SQLite 列,也许这将是一个可能的解决方案路径?无论如何,如果可能的话,我想找到一种方法来为两个项目使用相同的数据模型。

有没有办法安排 Zumero、Sql Server 和/或我的数据模型,以便它们可以协同工作?

作为一名自学成才的程序员,我对这一切真的很陌生,因此非常感谢任何和所有帮助!谢谢!!

【问题讨论】:

    标签: c# zumero


    【解决方案1】:

    这似乎更像是与实体框架有关,而不是 Zumero。您是否尝试使用相同的数据库上下文连接到 SQL Server 和 SQLite?由于这是一个相当大的问题,并且需要反复进行,我建议发送电子邮件至 support@zumero.com。

    【讨论】:

    • 在他们的网站上,他们说您可以通过电子邮件发送问题,或者在标记为 zumero 的 SO 上发布问题。我选择了这个选项,但当然,我可以另外发送电子邮件。
    【解决方案2】:

    Jeremy Sheeley 查看了我的代码,与我讨论了这个问题,并向我展示了一个可能的解决方案。他看着一个自学成才的程序员的代码,非常有礼貌。 :-)

    如果我正确理解答案,所问的问题是正确答案的倒退。 Jeremy 与我分享了一个代码示例,以帮助我了解如何构建将从 SQL Server 逆向工程的模型映射的代码,并允许 EF 正确地将它们与 SQLite 数据源一起使用。因此,我试图从从 SQLite 数据源设计的模型出发,但我需要将其反转,然后在数据上下文中应用值转换。

    using Microsoft.EntityFrameworkCore;
    using Microsoft.EntityFrameworkCore.Metadata;
    using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
    //...
    
    public partial class SQLiteEFDatabase : EFDatabase
    {
       //...
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            ConfigureValueConversions(modelBuilder);
        }
    
        //...
    
        private void ConfigureValueConversions(ModelBuilder modelBuilder)
        {
            foreach (var entityType in modelBuilder.Model.GetEntityTypes())
            {
                foreach (var property in entityType.GetProperties())
                {
                    if (property.ClrType == typeof(Guid))
                    {
                        property.SetValueConverter(new GuidToBytesConverter());
                    }
                }
    
                foreach (var property in entityType.GetProperties())
                {
                    if (property.ClrType == typeof(DateTime))
                    {
                        property.SetValueConverter(new DateTimeToStringConverter());
                    }
                }
            }
        }
    }
    

    非常感谢 Jeremy 提供的帮助!!!

    【讨论】:

      猜你喜欢
      • 2012-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-08
      • 2021-12-26
      • 2019-06-03
      相关资源
      最近更新 更多