Nhibernate 获取现有实体(如果存在)或创建新实体

Nhibernate 获取现有实体(如果存在)或创建新实体,nhibernate,fluent-nhibernate,domain-driven-design,s#arp-architecture,Nhibernate,Fluent Nhibernate,Domain Driven Design,S#arp Architecture,我正在导入数据库中可能存在或不存在的数据。我希望NHibernate将任何实体与现有的db-one关联起来(如果它存在的话)(可能只是设置主键/id),或者创建一个新的实体(如果它不存在的话)。我的框架(MVC2、NHibernate、Fluent)使用S#arp架构 我已将[HasUniqueDomainSignature]属性添加到类中,并将[DomainSignature]属性添加到要用于比较的属性中。我能想到的唯一方法(这不是一个可接受的解决方案,甚至可能不起作用)是以下方法(psued

我正在导入数据库中可能存在或不存在的数据。我希望NHibernate将任何实体与现有的db-one关联起来(如果它存在的话)(可能只是设置主键/id),或者创建一个新的实体(如果它不存在的话)。我的框架(MVC2、NHibernate、Fluent)使用S#arp架构

我已将[HasUniqueDomainSignature]属性添加到类中,并将[DomainSignature]属性添加到要用于比较的属性中。我能想到的唯一方法(这不是一个可接受的解决方案,甚至可能不起作用)是以下方法(psuedo C#):

}


正如你所看到的,这既杂乱无章,也毫无意义。再加上我对这本书有半打联想(主题、格式等),这没有任何意义。一定有一个简单的方法来做这件事,我错过了。我不是NHibernate的新手,但我绝对不是专家。

我可能不理解这个问题,但数据如何“可能存在于数据库中,也可能不存在于数据库中”?例如,如果一本书有两位作者,如果作者不存在,关系如何存储在数据库级别


似乎您正试图使用NHibernate导入数据(或创建实体,如果它不存在),但这似乎不正确。

大多数数据库实现都支持条件更新或插入语法。例如,甲骨文(Oracle)就有一个。结合映射中的Hibernate
块,您应该能够解决一些问题。我不知道Fluent,但我想它也支持这一点。

要知道我从来没有给出过答案,也没有认可过别人的答案。最后,我编写了一个新的SaveOrUpdate,它在持久化之前使用一个参数来检查是否存在。我还向域模型添加了一个属性,以便在保存/更新时覆盖(尽管在retrospect中,只有在更新时才会覆盖)

下面是代码,如果它能帮助其他陷入困境的人:

       public TEntity SaveOrUpdate<TEntity>(TEntity entity, bool checkForExistingEntity)
    {
        IRepository<TEntity> repository = new Repository<TEntity>();
        if (checkForExistingEntity) {

            if (entity is Entity) {
                IEnumerable<PropertyInfo> props = (entity as Entity).GetSignatureProperties();
                Dictionary<string, object> parameters =
                    props.ToDictionary(propertyInfo => propertyInfo.Name, propertyInfo => propertyInfo.GetValue(entity, null));
                TEntity duplicateEntity = repository.FindOne(parameters);
                if (duplicateEntity != null) {
                    // Update any properties with the OverwriteOnSaveUpdate attribute
                    foreach (var property in RepositoryHelper.GetUpdatableProperties(typeof(TEntity)))
                    {
                        object initialValue = property.GetValue(entity, null);
                        property.SetValue(duplicateEntity, initialValue, null);
                    }
                    // Fill in any blank properties on db version
                    foreach (var property in typeof(TEntity).GetProperties())
                    {
                        if (property.GetValue(duplicateEntity, null) == null) {
                            object initialValue = property.GetValue(entity, null);
                            property.SetValue(duplicateEntity, initialValue, null);
                        }
                    }
                    return duplicateEntity;
                }
            }
        }
        return SaveOrUpdate(entity);
    }
public tenty SaveOrUpdate(tenty实体,bool checkForExistingEntity)
{
IRepository repository=新存储库();
如果(检查是否存在){
如果(实体是实体){
IEnumerable props=(实体作为实体).GetSignatureProperties();
字典参数=
ToDictionary(propertyInfo=>propertyInfo.Name,propertyInfo=>propertyInfo.GetValue(entity,null));
tenty duplicateEntity=repository.FindOne(参数);
if(duplicateEntity!=null){
//使用OverwriteOnSaveUpdate属性更新任何属性
foreach(RepositoryHelper.getUpdateableProperties(typeof(tenty))中的var属性)
{
对象initialValue=property.GetValue(实体,null);
SetValue(duplicateEntity,initialValue,null);
}
//在db版本中填写任何空白属性
foreach(typeof(tenty).GetProperties()中的var属性)
{
if(property.GetValue(duplicateEntity,null)==null){
对象initialValue=property.GetValue(实体,null);
SetValue(duplicateEntity,initialValue,null);
}
}
返回重复实体;
}
}
}
返回SaveOrUpdate(实体);
}

您是对的,我正在尝试使用NHibernate导入数据。基本上,我有一个系统,其中已经有一些作者(和书籍)。我得到的数据源中有更多的作者(和书籍)。我想获取该提要并将我还没有的书籍/作者导入到我的系统中。导入过程中还有很多工作要做,这就是为什么我要转换为域模型并使用NHibernate进行导入(而不是将其保存在数据集中并使用ADO导入数据。这可能吗?我猜这是可能的,但我不确定如何做。我的建议是使用不同的工具进行导入。
       public TEntity SaveOrUpdate<TEntity>(TEntity entity, bool checkForExistingEntity)
    {
        IRepository<TEntity> repository = new Repository<TEntity>();
        if (checkForExistingEntity) {

            if (entity is Entity) {
                IEnumerable<PropertyInfo> props = (entity as Entity).GetSignatureProperties();
                Dictionary<string, object> parameters =
                    props.ToDictionary(propertyInfo => propertyInfo.Name, propertyInfo => propertyInfo.GetValue(entity, null));
                TEntity duplicateEntity = repository.FindOne(parameters);
                if (duplicateEntity != null) {
                    // Update any properties with the OverwriteOnSaveUpdate attribute
                    foreach (var property in RepositoryHelper.GetUpdatableProperties(typeof(TEntity)))
                    {
                        object initialValue = property.GetValue(entity, null);
                        property.SetValue(duplicateEntity, initialValue, null);
                    }
                    // Fill in any blank properties on db version
                    foreach (var property in typeof(TEntity).GetProperties())
                    {
                        if (property.GetValue(duplicateEntity, null) == null) {
                            object initialValue = property.GetValue(entity, null);
                            property.SetValue(duplicateEntity, initialValue, null);
                        }
                    }
                    return duplicateEntity;
                }
            }
        }
        return SaveOrUpdate(entity);
    }