我想创建一个使用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数据库时如何实现呢?
答案 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);
}
}