如何为NoSQL应用程序创建域实体

时间:2015-05-14 17:19:06

标签: c# mongodb

我想创建一个使用NoSQL数据库的应用程序,它可以很好地与我的域实体一起使用。

现在我创建一个"域实体"对于MongoDB,我必须定义如下:

public class User
{
    [BsonId]
    public int Id {get;set;}

    [BsonElement("Username")]
    public string Username {get;set;}

    [BsonElement("Email")]
    public string Email {get;set;}
}

但这意味着我的实体不是无知的持久性。那么在使用像MongoDB这样的NoSQL数据库时如何实现呢?

2 个答案:

答案 0 :(得分:0)

一种方法是在您的域中定义POCO类,如此

namespace MyApp.Domain
{
    public class User
    {
        public int Id { get; set; }
        public string Username { get; set; }
        public string Email { get; set; }
    }
}   

并为每个持久性类型定义相同的类,例如MongoDB

namespace MyApp.MongoDb
{
    public class User
    {
        [BsonId]
        public int Id { get; set; }

        [BsonElement("Username")]
        public string Username { get; set; }

        [BsonElement("Email")]
        public string Email { get; set; }
    }
}

您的业务逻辑将通过存储库接口与您的域类进行交互,当您持久保存数据时,您只需复制该实例。

您不必手动编写复制数据代码,因为automapper可以帮助您。或者,您可以使用我的简化代码在以下域类之间复制数据:

/// <summary>
        /// Copy public fields from an instance of the source type TV to an instance of the destination type T.
        ///  A source property will be copied if there is a property in the destination type with the same name.
        /// For instance, TV.Name will be copied to T.Name
        /// </summary>
        /// <typeparam name="T">The destination type</typeparam>
        /// <typeparam name="TV">The source type</typeparam>
        /// <param name="input">The source data</param>
        /// <param name="existingInstance">The instance that we want to copy values to, if it is null a new instance will be created</param>
        /// <returns>An instance of type T</returns>
        public static T CopyFields< TV,T>(TV input, T existingInstance=null)where  T:class where TV:class 
        {
            var sourcePublicFields = typeof (TV).GetProperties();

            var instance =existingInstance ?? Activator.CreateInstance<T>();

            var destinationPublicFields = typeof(T).GetProperties();

            Debug.WriteLine("Copying data from source type {0} to destination type {1}", typeof(TV), typeof(T));

            foreach (var field in sourcePublicFields)
            {
                var destinationField = destinationPublicFields.FirstOrDefault(it => it.Name == field.Name);
                if (destinationField == null || destinationField.PropertyType != field.PropertyType)
                {
                    Debug.WriteLine("No Destination Field matched with the source field. Source Field  name {0}, source field type {1} ", field.Name, field.PropertyType);
                    continue;
                }

                var sourceValue = field.GetValue(input);
                //Set the value
                destinationField.SetValue(instance,sourceValue);

            }


            return instance;
        }

答案 1 :(得分:0)

您的实体可以是POCO对象。

您可以使用ConvetionRegistry解决几乎所有规则。 Fox示例此代码将Id设置为字符串并忽略额外字段。

var convention = new ConventionPack { 
    new IgnoreExtraElementsConvention(true), 
    new IdGeneratorConvention() };
ConventionRegistry.Register("CubeConventions", convention, x => true);

public class IdGeneratorConvention : ConventionBase, IPostProcessingConvention
{
    public void PostProcess(BsonClassMap classMap)
    {
        var idMemberMap = classMap.IdMemberMap;
        if (idMemberMap == null || idMemberMap.IdGenerator != null)
        {
            return;
        }
        idMemberMap.SetIdGenerator(StringObjectIdGenerator.Instance);
    }
}