2

我们共享一个 poco 的

  • ServiceStack 网络服务
  • 使用 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 中。幸运的是,他们有一个 AutoMapper 类可以在运行时执行此操作。

不知道该怎么办。我失败的想法包括:

  • 尝试使用:[Conditional("DEBUG")]。但这无济于事

  • 似乎 sqlite.net 使用了自己的属性

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

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

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

    [索引] [索引] public string UserAccountId { get; 放; }

  • 我试图把它变成两个单行但 c# VS 抱怨

#if __MOBILE__ [Indexed]  #endif 
#if __MOBILE__ [Index]    #endif

最后,** APPEARS ** 唯一可行的方法是将接口保留为类的单一定义,并有许多具体的类以不同的方式装饰。

有任何想法吗??

4

4 回答 4

4

如果您要按照鲍勃叔叔的清洁架构来构建您的代码,您不会尝试将单一表示用于许多不同的目的,因为它会导致您的依赖项从高级策略向外指向外圈。

清洁架构

来源:https ://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.html

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

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

于 2017-12-22T16:20:38.567 回答
0

Mason 的建议是创建一个流利的模型生成器。因为这目前不存在???在 ServiceStack.OrmLine 和 SqlLite.net 中,我假设我必须构建它。

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

modelBuilder 
    .Entity<Person>() 
    .Property(t => t.Name) 
    .HasColumnAnnotation( 
        "Index",  
        new IndexAnnotation(new IndexAttribute("IX_Name") { IsUnique = true }));

我的伪代码版本如下所示:

modelBuilder 
    .Entity<UserEntity>() 
    .Property(t => t.UserAccountId) 
    .AddColumnIndex(new IndexAnnotation(new IndexAttribute("IX_Name") {});
于 2017-12-22T18:08:08.577 回答
0

所以,鲍勃大叔和芬顿的建议基本上是我最后的选择。对界面进行更改。

我将使用 Re-sharper 更新所有类的类..

这应该有效。

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 

这应该有效。

缺点

  1. 需要在控制器级别维护多个 4x 复制构造函数。
  2. 一节课现在是四节课。
于 2017-12-22T17:24:49.817 回答
0

显然这种语法是有效的,也应该可以工作。

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; }
于 2017-12-22T20:22:41.717 回答