Trong việc tìm kiếm của tôi cho một bộ lọc cơ sở dữ liệu phiên bản toàn cho một ứng dụng, tôi đã viết đoạn mã sau là gì:cách tốt nhất để cung cấp một AutoMappingOverride cho một giao diện trong automapper fluentnhibernate
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FluentNHibernate.Automapping;
using FluentNHibernate.Automapping.Alterations;
using FluentNHibernate.Mapping;
using MvcExtensions.Model;
using NHibernate;
namespace MvcExtensions.Services.Impl.FluentNHibernate
{
public interface IVersionAware
{
string Version { get; set; }
}
public class VersionFilter : FilterDefinition
{
const string FILTERNAME = "MyVersionFilter";
const string COLUMNNAME = "Version";
public VersionFilter()
{
this.WithName(FILTERNAME)
.WithCondition("Version = :"+COLUMNNAME)
.AddParameter(COLUMNNAME, NHibernateUtil.String);
}
public static void EnableVersionFilter(ISession session,string version)
{
session.EnableFilter(FILTERNAME).SetParameter(COLUMNNAME, version);
}
public static void DisableVersionFilter(ISession session)
{
session.DisableFilter(FILTERNAME);
}
}
public class VersionAwareOverride : IAutoMappingOverride<IVersionAware>
{
#region IAutoMappingOverride<IVersionAware> Members
public void Override(AutoMapping<IVersionAware> mapping)
{
mapping.ApplyFilter<VersionFilter>();
}
#endregion
}
}
Nhưng, kể từ khi ghi đè không hoạt động trên các giao diện, tôi đang tìm cách để thực hiện điều này. Hiện nay tôi đang sử dụng theo cách này (chứ không cồng kềnh) cho mỗi lớp mà thực hiện giao diện:
public class SomeVersionedEntity : IModelId, IVersionAware
{
public virtual int Id { get; set; }
public virtual string Version { get; set; }
}
public class SomeVersionedEntityOverride : IAutoMappingOverride<SomeVersionedEntity>
{
#region IAutoMappingOverride<SomeVersionedEntity> Members
public void Override(AutoMapping<SomeVersionedEntity> mapping)
{
mapping.ApplyFilter<VersionFilter>();
}
#endregion
}
Tôi đã được nhìn IClassmap giao diện vv, nhưng họ dường như không cung cấp một cách tiếp cận phương pháp ApplyFilter , vì vậy tôi không có một đầu mối ở đây ...
Vì tôi có lẽ không phải là người đầu tiên có vấn đề này, tôi khá chắc chắn rằng nó sẽ là có thể; Tôi chỉ không khá chắc chắn cách làm việc này ..
EDIT: Tôi đã nhận được một chút gần gũi hơn với một giải pháp chung:
Đây là cách tôi đã cố gắng để giải quyết nó:
Sử dụng một lớp tổng quát để thực hiện thay đổi đến các lớp học thực hiện một giao diện:
public abstract class AutomappingInterfaceAlteration<I> : IAutoMappingAlteration
{
public void Alter(AutoPersistenceModel model)
{
model.OverrideAll(map =>
{
var recordType = map.GetType().GetGenericArguments().Single();
if (typeof(I).IsAssignableFrom(recordType))
{
this.GetType().GetMethod("overrideStuff").MakeGenericMethod(recordType).Invoke(this, new object[] { model });
}
});
}
public void overrideStuff<T>(AutoPersistenceModel pm) where T : I
{
pm.Override<T>(a => Override(a));
}
public abstract void Override<T>(AutoMapping<T> am) where T:I;
}
Và một thực hiện cụ thể:
01.235.public class VersionAwareAlteration : AutomappingInterfaceAlteration<IVersionAware>
{
public override void Override<T>(AutoMapping<T> am)
{
am.Map(x => x.Version).Column("VersionTest");
am.ApplyFilter<VersionFilter>();
}
}
Đáng tiếc là tôi nhận được lỗi sau bây giờ:
[InvalidOperationException: Collection was modified; enumeration operation may not execute.]
System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource) +51
System.Collections.Generic.Enumerator.MoveNextRare() +7661017
System.Collections.Generic.Enumerator.MoveNext() +61
System.Linq.WhereListIterator`1.MoveNext() +156
FluentNHibernate.Utils.CollectionExtensions.Each(IEnumerable`1 enumerable, Action`1 each) +239
FluentNHibernate.Automapping.AutoMapper.ApplyOverrides(Type classType, IList`1 mappedProperties, ClassMappingBase mapping) +345
FluentNHibernate.Automapping.AutoMapper.MergeMap(Type classType, ClassMappingBase mapping, IList`1 mappedProperties) +43
FluentNHibernate.Automapping.AutoMapper.Map(Type classType, List`1 types) +566
FluentNHibernate.Automapping.AutoPersistenceModel.AddMapping(Type type) +85
FluentNHibernate.Automapping.AutoPersistenceModel.CompileMappings() +746
EDIT 2: Tôi quản lý để có được một chút nữa; bây giờ tôi gọi "Override" sử dụng phản chiếu cho mỗi lớp mà thực hiện giao diện:
public abstract class PersistenceOverride<I>
{
public void DoOverrides(AutoPersistenceModel model,IEnumerable<Type> Mytypes)
{
foreach(var t in Mytypes.Where(x=>typeof(I).IsAssignableFrom(x)))
ManualOverride(t,model);
}
private void ManualOverride(Type recordType,AutoPersistenceModel model)
{
var t_amt = typeof(AutoMapping<>).MakeGenericType(recordType);
var t_act = typeof(Action<>).MakeGenericType(t_amt);
var m = typeof(PersistenceOverride<I>)
.GetMethod("MyOverride")
.MakeGenericMethod(recordType)
.Invoke(this, null);
model.GetType().GetMethod("Override").MakeGenericMethod(recordType).Invoke(model, new object[] { m });
}
public abstract Action<AutoMapping<T>> MyOverride<T>() where T:I;
}
public class VersionAwareOverride : PersistenceOverride<IVersionAware>
{
public override Action<AutoMapping<T>> MyOverride<T>()
{
return am =>
{
am.Map(x => x.Version).Column(VersionFilter.COLUMNNAME);
am.ApplyFilter<VersionFilter>();
};
}
}
Tuy nhiên, vì một lý do này hay cách khác tôi tạo ra các file hbm không chứa bất kỳ "lọc" các lĩnh vực .... Có lẽ ai đó có thể giúp tôi thêm một chút bây giờ không ??