멀티 컬럼 고유 제약 조건 Fluentnhibernate Automap Via Convention.
-
12-11-2019 - |
문제
FluentNhibernate의 Automap 지원은 규칙을 통해 다중 열 고유 제약 조건을 생성합니까?
단일 열 고유 제약 조건을 쉽게 만들 수 있습니다.
public void Apply(IPropertyInstance instance)
{
if(instance.Name.ToUpper().Equals("NAME"))
instance.Unique();
}
.
Acceptance 기준을 사용하여 ReferenceEntity
유형 만 찾습니다.
이제 여러 열 고유 제약 조건을 만들고 싶습니다. 나는 동일한 고유 키의 일부를 형성 할 수 있도록 속성을 사용하여 엔티티의 속성을 장식 할 계획을 세웠습니다. 즉 :
public class Foo : Entity
{
[Unique("name_parent")]
public virtual string Name { get; set; }
public virtual string Description { get; set; }
[Unique("name_parent")]
public virtual Bar Parent { get; set; }
}
.
및 컨벤션이 이러한 속성을 찾고 동일한 고유 키를 공유하는 모든 필드에 고유 한 것을 만듭니다.
IProperyConvention
인터페이스를 사용하면 특정 인스턴스 (열)에서 Unique
를 지정하지만 다른 열에 대한 가시성이 없지만
업데이트
이것을 게시하는 과정은 나에게 더 많은 것을 생각하게 도와 줬어, 그래서 나는 이것을 썼다 :
var propertyInfo = ((PropertyInstance)(instance)).EntityType.GetMember(instance.Name).FirstOrDefault();
if (propertyInfo != null)
{
var attributes = propertyInfo.GetCustomAttributes(false);
var uniqueAttribute = attributes.OfType<UniqueAttribute>().FirstOrDefault();
if (uniqueAttribute != null)
{
instance.UniqueKey(uniqueAttribute.Key);
}
}
.
코드를 스텝핑하는 코드를 두 번 (예상대로) 두 번 히트 (예상대로) 작성한 제한 조건.
ADD CONSTRAINT foo_name_key UNIQUE(name);
.
내가 예상했을 때
ADD CONSTRAINT name_parent UNIQUE(name, bar);
.
업데이트 2
automap config에서 instance.UniqueKey(...)
메소드를 사용할 때 올바른 고유 키를 지정할 수 있습니다.
.Override<Foo>(map => {
map.Map(x => x.Name).UniqueKey("name_parent");
map.Map(x => x.Description);
map.References(x => x.Parent).UniqueKey("name_parent");
})
.
이것은 자동 매퍼에 문제가있을 수 있습니다. 확실하지 않습니다. 특성 장식을 통해 일반적이지 않은 것과 같지만 현재 DataModel이 도메인 요구 사항을 반영하는 것입니다.
해결책
이이 일을 할 때 2 개의 규칙을 만들었습니다. 하나는 AttributePropertyConvention이었고 다른 하나는 IreferenCeConvention입니다.내 속성은 다음과 같이 보였습니다.
public class UniqueAttribute : Attribute
{
public UniqueAttribute(string uniqueKey)
{
UniqueKey = uniqueKey;
}
public string UniqueKey { get; set; }
public string GetKey()
{
return string.Concat(UniqueKey, "Unique");
}
}
.
내 재산 규칙 :
public class UniquePropertyConvention : AttributePropertyConvention<UniqueAttribute>
{
protected override void Apply(UniqueAttribute attribute, IPropertyInstance instance)
{
instance.UniqueKey(attribute.GetKey());
}
}
.
및 마지막으로 참조 규칙 :
public class UniqueReferenceConvention : IReferenceConvention
{
public void Apply(IManyToOneInstance instance)
{
var p = instance.Property.MemberInfo;
if (Attribute.IsDefined(p, typeof(UniqueAttribute)))
{
var attribute = (UniqueAttribute[])p.GetCustomAttributes(typeof(UniqueAttribute), true);
instance.UniqueKey(attribute[0].GetKey());
}
}
}
.
당신의 시나리오에서는이 작업을 수행합니다.
다른 팁
하지 마십시오 .... 귀하의 도메인에서 고유성을 적용하십시오.)