一周前我问how to propagate a parameter for joins in a ORM。建议的解决方案看起来很有希望 - 使用NHibernate过滤器。这就是我正在做的事情:
过滤类:
public class VersionFilter : FilterDefinition
{
public static readonly string Name = typeof(VersionFilter).AssemblyQualifiedName;
public static readonly string Parameter = "AsOf";
private static readonly string SqlParameter = ":" + Parameter;
private static readonly string Condition
= " ISNULL(" + SqlParameter + ") AND ( ISNULL(ValidTo) )" +
" OR ( ValidFrom < " + SqlParameter + " AND " + SqlParameter + " <= ValidTo )"
;
private static readonly IDictionary<string, IType> ParameterTypes =
new Dictionary<string, IType>
{
{Parameter, NHibernateUtil.Int64}
}
;
public VersionFilter(): base(Name, Condition, ParameterTypes, true)
{
}
}
在Main:
public class Program
{
static void Main(string[] args)
{
log.Info("VersionedDataModel1.Program::start");
try
{
var cfg = new Configuration();
cfg.Configure();
cfg.AddFilterDefinition(new VersionFilter());
var types = DomainClasses(typeof(Program).Assembly, "VersionedDataModel1.Domain");
foreach (Type type in types)
{
cfg.AddInputStream(HbmSerializer.Default.Serialize(type));
}
var sessionFactory = cfg.BuildSessionFactory();
{
var schema = new SchemaExport(cfg);
schema.Drop(false, true);
schema.Execute(false, true, false);
//new SchemaExport(cfg).Drop(false, true);
//new SchemaExport(cfg).Execute(false, true, false);
//new SchemaUpdate(cfg).Execute(false, true);
}
}
}
}
其中一个实体类:
[Class]
public class Store : BaseEntity
{
private ICollection<Product> _products = new List<Product>();
private ICollection<Employee> _staff = new List<Employee>();
[Property(NotNull = true)]
public virtual string Name { get; set; }
[Set(0, Table = "ProductsInStore", Lazy = CollectionLazy.False, Cascade = "none")]
[Key(1, Column = "StoreId")]
[ManyToMany(2, Column = "ProductId", ClassType = typeof(Product))]
public virtual ICollection<Product> Products { get { return _products; } set { _products = value; } }
[Key(1, Column = "StoreId")]
[OneToMany(2, ClassType = typeof(Employee))]
public virtual ICollection<Employee> Staff { get { return _staff; } set { _staff = value; } }
public virtual void AddProduct(Product product)
{
product.StoresStockedIn.Add(this);
Products.Add(product);
}
public virtual void AddEmployee(Employee employee)
{
employee.Store = this;
Staff.Add(employee);
}
}
要查询数据,请执行以下操作:
public IEnumerable<Product> QueryAllProducts(long? asOf)
{
using (var session = SessionFactory.OpenSession())
{
session.EnableFilter(VersionFilter.Name).SetParameter(VersionFilter.Parameter, asOf);
return session.QueryOver<Product>().List<Product>();
}
}
在NHibernate调试日志中,我看到以下内容。当我构造SessionFactory时。我看到以下错误,我不确定如何解释:
2015-04-30 13:53:32,398 [1] ERROR NHibernate.Cfg.Configuration - filter-def for filter named 'VersionedDataModel1.VersionFilter, VersionedDataModel1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' was never used to filter classes nor collections.
This may result in unexpected behavior during queries
在日志中,我看到没有对过滤器的引用,也没有过滤我的Product集合。可能是我错过了这个概念。
我的想法是为整个会话应用此过滤器(VersionFilter),以便查询的所有实体都将使用此addidional WHERE ...
条件。
因此是问题 - 我对Filter / FilterDefinition缺少什么?
谢谢!
答案 0 :(得分:1)
您已经将过滤器注册为nhibernate,现在您必须在映射类或集合中调用引用。
我从未使用属性映射,但我认为您需要使用Import-Csv -Path .\test.csv | ForEach-Object {
$acct = Get-ADUser -Filter "employeeNumber -eq $($_.'Manager User Sys ID')" |
select -Expand SamAccountName
$_ | select *,@{Name='managerUsername';Expression={$acct}}
} | Export-Csv -Path .\simpletest.csv -NoTypeInformation
将过滤器与实体(类级别)相关联
或像这样的动态:
NHibernate.Mapping.Attributes.Filter
您可以在nhibernate文档中阅读更多here。