NHibernate'i F # türü sistemiyle kullanmayı denemek için yeterince cesur olmadım, ancak F # derleyicisi tarafından gerçekten neyin oluşturulduğunun perspektifinden bakmaya yardımcı olabilir.
Yansıtılmış Birliğinize yansıtıcıya bakarsanız, aslında oluşturulan üç sınıf vardır (ve özel hata ayıklama proxy'lerini sayıyorsanız daha fazla).
public abstract class RequestInfo : IStructuralEquatable, IComparable, IStructuralComparable
Birinci sınıf, RequestInfo, soyutdur ve aslında, birliğin diğer türleri tarafından uygulanır. bunu yaptığında
// Nested Types
[Serializable, DebuggerTypeProxy(typeof([email protected])), DebuggerDisplay("{__DebugDisplay()}")]
public class _Id : Program.RequestInfo
{
// Fields
[DebuggerBrowsable(DebuggerBrowsableState.Never), CompilerGenerated, DebuggerNonUserCode]
public readonly int id1;
// Methods
[CompilerGenerated, DebuggerNonUserCode]
public _Id(int id1);
}
[Serializable, DebuggerTypeProxy(typeof([email protected])), DebuggerDisplay("{__DebugDisplay()}")]
public class _Name : Program.RequestInfo
{
// Fields
[DebuggerBrowsable(DebuggerBrowsableState.Never), CompilerGenerated, DebuggerNonUserCode]
public readonly string name1;
// Methods
[CompilerGenerated, DebuggerNonUserCode]
public _Name(string name1);
}
yüzden:
let r=Id(5)
let s=Name("bob")
r ve s sırasıyla _ID ve _name örnekleridir.
Yani sorunun cevabı aşağıdaki soruların birine muhtemel cevabı:
- ben nhibernate içinde soyut bir sınıfa haritasına nasıl?
- NHibernate'i bir fabrika yöntemini nasıl kullanabilirim?
- Harita nasıl oluşturulur? Değişmez nesnelere Nhibernate?
- NHibernate'de (muhtemelen IUserType ile) özel bir türü nasıl uygularım?
Maalesef, bunlardan herhangi birine tutarlı bir cevap vermek için yeterince bilgim yok, ama eminim ki buradaki bir başkası bu üç çözümden en az birini yaptı.
Örneğin, bir ayrımcı sütunu kullanarak Kalıtım Stratejileri için kullanılan yöntemlerin aynısını kullanabileceğinizi düşünmekteyim, ancak bir varsayılan kurucunun yokluğunun bu sorunu çözdüğünden korkuyorum. Bu yüzden özel bir tip kullanmanın çözüm olduğunu düşünmeye meyilliyim. Bazı işe yaramaz sonra
, burada (muhtemelen arabası ve ya kırık) özel kullanıcı tipi var:
type RequestInfo =
| Id of int
| Name of string
type RequestInfoUserType() as self =
interface IUserType with
member x.IsMutable = false
member x.ReturnedType = typeof<RequestInfo>
member x.SqlTypes = [| NHibernate.SqlTypes.SqlType(Data.DbType.String); NHibernate.SqlTypes.SqlType(Data.DbType.Int32); NHibernate.SqlTypes.SqlType(Data.DbType.String) |]
member x.DeepCopy(obj) = obj //Immutable objects shouldn't need a deep copy
member x.Replace(original,target,owner) = target // this might be ok
member x.Assemble(cached, owner) = (x :> IUserType).DeepCopy(cached)
member x.Disassemble(value) = (x :> IUserType).DeepCopy(value)
member x.NullSafeGet(rs, names, owner)=
// we'll use a column as a type discriminator, and assume the first mapped column is an int, and the second is a string.
let t,id,name = rs.GetString(0),rs.GetInt32(1),rs.GetString(2)
match t with
| "I" -> Id(id) :> System.Object
| "N" -> Name(name) :> System.Object
| _ -> null
member x.NullSafeSet(cmd, value, index)=
match value with
| :? RequestInfo ->
let record = value :?> RequestInfo
match record with
| Id(i) ->
cmd.Parameters.Item(0) <- "I"
cmd.Parameters.Item(1) <- i
| Name(n) ->
cmd.Parameters.Item(0) <- "N"
cmd.Parameters.Item(2) <- n
| _ -> raise (new ArgumentException("Unexpected type"))
member x.GetHashCode(obj) = obj.GetHashCode()
member x.Equals(a,b) =
if (Object.ReferenceEquals(a,b)) then
true
else
if (a=null && b=null) then
false
else
a.Equals(b)
end
Bu kod kesinlikle daha genel yapılmış olabilir ve muhtemelen gerçek etki alanı tabakasında olmamalı, ama ben IUserType bir F # uygulamasında bir bıçak almak yararlı olacağını düşündüm.
Kişisel eşleme dosyası daha sonra böyle bir şey yapsın:
<property name="IdOrName" type="MyNamespace.RequestInfoUserType, MyAssembly" >
<column name="Type"/>
<column name="Id"/>
<column name="Name"/>
</property>
Muhtemelen uzakta özel UserType kodunda küçük çimdik ile "Tür" için bir sütun olmadan alabilirsiniz.
Bu özel kullanıcı türlerinin, daha önce özel kullanıcı türleriyle gerçekten çalışmadığım için sorgularla/ICriteria ile nasıl çalıştığını bilmiyorum.
Çok ilginç bir soru. Ben hem NHibernate hem de F # 'da oldukça akıcıyım, biraz zaman aldığımda bununla başa çıkacağım –
En azından benim deneyimlerimde, NHibernate ile F # kullanarak çoğunlukla zor zamanlar geçirdim, çünkü çoğunlukla NHibernate varsayılan bir kurucuya sahip olmak için nesneler gerektirir sık sık sendika türleri, kayıt türleri ve çoğu sınıf için geçerli değildir) ve sınıflara değerler atamak için mutabiliteye dayanır (F # sınıfı tanımlarında sıkça karşılaşmak sıkıcıdır). Daha sık olmamakla birlikte, veritabanını kendi mirco-ORM'imi yuvarlayarak F # ile oynayacağım. – Juliet
Evet, son projemizde sadece eski eski nesne tiplerine yapıştık, böylece NHibernate ile güzelce oynayacaklardı. Bu sefer biraz dalıp biraz daha gerçekçi modeller denemek istiyorum. – MichaelGG