ormlite-servicestack,sqlite.net,C#,Xamarin,Custom Attributes,ormlite Servicestack,Sqlite.net" /> ormlite-servicestack,sqlite.net,C#,Xamarin,Custom Attributes,ormlite Servicestack,Sqlite.net" />

C# C属性hell-两个不同SQL平台上移动和服务器之间共享的一个类

C# C属性hell-两个不同SQL平台上移动和服务器之间共享的一个类,c#,xamarin,custom-attributes,ormlite-servicestack,sqlite.net,C#,Xamarin,Custom Attributes,ormlite Servicestack,Sqlite.net,我们与您共享一个poco ServiceStack Web服务 使用MySQL的ServiceStack Orm 使用Sqlite.net的Xamarin移动客户端。 问题是共享类已经变得一团糟 [PrimaryKey, AutoIncrement] public int Id { get; set; } #if __MOBILE__ [Indexed] #else [Index] #endif public str

我们与您共享一个poco

ServiceStack Web服务 使用MySQL的ServiceStack Orm 使用Sqlite.net的Xamarin移动客户端。 问题是共享类已经变得一团糟

        [PrimaryKey, AutoIncrement]
        public int Id { get; set; }
#if __MOBILE__
        [Indexed]
#else
        [Index]
#endif
        public string UserAccountId { get; set; }
#if __MOBILE__
        [Indexed]
#else
        [Index]
#endif
如果还不够糟糕的话,我需要

约束数据库中每个字段的长度。。。。 在MongoDb中保存这些对象。幸运的是,他们有一个汽车制造商 类,该类在运行时执行此操作。 不知道该怎么办。我失败的想法包括:

尝试使用:[ConditionalDEBUG]。但它对此毫无作用

看来sqlite.net使用了它自己的属性

[AttributeUsage AttributeTargets.Property] 公共类IndexedAttribute:属性

所以它找不到Mysql[Index]属性

可以尝试在每个属性上包含两个属性

[索引] [索引] 公共字符串UserAccountId{get;set;}

我试图把它变成两个一行的人,但c VS抱怨

最后,**看起来**唯一有效的方法就是保持接口作为类的单一定义,并有许多具体的类以不同的方式进行修饰


有什么想法吗

如果您要按照Bob叔叔的干净体系结构来构建代码,您就不会试图使用一个表示来实现许多不同的目的,因为它会导致依赖项从高级策略指向外部

资料来源:

实际上,您可以将一个实体与企业业务规则一起放在中心圆圈中,但您用于存储/检索特定数据库数据的数据应该在您的框架和驱动程序圆圈中找到出路


所有这些特定于数据库的属性都属于蓝色圆圈中的DTO,而不是中间的实体。

因此,Bob叔叔和Fenton的建议基本上是我最后的选择。对接口进行更改

我将使用更锐化的用户更新所有类

这应该行得通

namespace Evaluation.Entitys
{
    public interface IUserEntity
    {
        string UserAccountId { get; set; }
    }

    public class UserEntity : IUserEntity
    {
        public string UserAccountId { get; set; }

        public UserEntity()
        {

        }
    }

    public class UserEntityTransport : IUserEntity
    {
        public string UserAccountId { get; set; }

        public UserEntityTransport(IUserEntity e)
        {
            UserAccountId = e.UserAccountId;
        }
    }
}
#if __MOBILE__

namespace Evaluation.Moible 
{


    using SQLite;
    using SQLite.Net;
    public class UserEntityMobileDB : IUserEntity
    {
        [Index]
        public string UserAccountId { get; set; }
        public UserEntityMobileDB(IUserEntity e)
        {
            UserAccountId = e.UserAccountId;
        }
    }
}
#endif

#if __WIN32__
namespace Evaluation.Server
{
    using Evaluation.Entitys;
    using ServiceStack.DataAnnotations;
    using SQLite;

    public class UserEntityServerDB : IUserEntity
    {
        [Indexed]
        public string UserAccountId { get; set; }

        public UserEntityServerDB(IUserEntity e)
        {
            UserAccountId = e.UserAccountId;

        }
    }
}
#endif 
这应该行得通

缺点

需要在控制器上维护多个4x副本构造函数 数量 一节课现在是四节课。
梅森的建议是创建一个流畅的模型生成器。因为这目前不存在???在ServiceStack.OrmLine和SqlLite.net中,我假设我必须构建它

我从实体框架中找到了这个代码示例

modelBuilder 
    .Entity<Person>() 
    .Property(t => t.Name) 
    .HasColumnAnnotation( 
        "Index",  
        new IndexAnnotation(new IndexAttribute("IX_Name") { IsUnique = true }));
我的psudocode版本如下所示:

modelBuilder 
    .Entity<UserEntity>() 
    .Property(t => t.UserAccountId) 
    .AddColumnIndex(new IndexAnnotation(new IndexAttribute("IX_Name") {});

显然,这种语法是有效的,也应该有效

using SQLite;
using ORMLite = ServiceStack.DataAnnotations;

[ORMLite.PrimaryKey, ORMLite.AutoIncrement]
[SQLite.PrimaryKey, SQLite.AutoIncrement]
public int Id { get; set; }

[Indexed,Index]
public string UserAccountId { get; set; }

如果你有所有这些属性,那就不是POCO。使用流畅的模型生成器而不是属性可能是一个优势。你的权利,这不是poco。问:我假设我需要自己构建ModelBuilder类。是否有一些通用框架可以用作覆盖层?我假设EntityFramework中的一个不起作用。我不熟悉ServiceStack.OrmLite,所以很遗憾,我不知道您有哪些选项。显然,我们可以定义这两个选项。所以这个语法是有效的[Index,Index]公共字符串UserAccountIdSo,基本上是我最后的选择,keep和interface以及每个实现的多个具体类。我将在下面提供一个示例。
using SQLite;
using ORMLite = ServiceStack.DataAnnotations;

[ORMLite.PrimaryKey, ORMLite.AutoIncrement]
[SQLite.PrimaryKey, SQLite.AutoIncrement]
public int Id { get; set; }

[Indexed,Index]
public string UserAccountId { get; set; }