0

我和我的团队正在 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 通过信息同步时,它text在 SQLite 文件中创建了一个类型列。我尝试使用直接从 SQL Server 逆向工程的数据模型,并使用它来创建 SQLite 文件,列类型为datetime.

我还尝试使用protected override void OnModelCreating(ModelBuilder modelBuilder)SQL Server 逆向工程师提供的,这给出了以下错误消息:"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 知道一种方法,我可以创建一个模型,该属性是DateTimeC# 中的类型,即使 Zumero 正在创建一个类型的 SQLite 列text,也许这将是一个可能的解决方案路径?无论如何,如果可能的话,我想找到一种方法来为两个项目使用相同的数据模型。

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

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

4

2 回答 2

1

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

于 2020-02-05T15:51:38.883 回答
0

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 的帮助!!!

于 2020-02-06T14:27:38.703 回答