簡體   English   中英

有沒有辦法使fluent-nhibernate使用QueryOver將ValueObject的值與字符串進行比較?

[英]Is there a way to get fluent-nhibernate to compare a ValueObject's value to a string using QueryOver?

在弗拉基米爾·霍里科夫(Vladimir Khorikov)的一些DDD課程之后,我將一些原始的類屬性抽象為ValueObjects。 例如,我的Account實體的Username屬性是一個字符串,但是為了將其驗證為域概念,我創建了一個Username類型。

這導致QueryOver停止工作,請參見代碼。

我收到異常: NHibernate.QueryException: 'could not resolve property: Username.Value of: PtPro.Domain.Account.Account'

// Account.cs
public class Account : AggregateRoot
    {
        private string _username;
        public virtual Username Username
        {
            get => (Username)_username;
            set => _username = value;
        }
    } // Rest of class removed for brevity

// AccountMap.cs
    public class AccountMap : ClassMap<Account>
    {
        public AccountMap()
        {
            Id(x => x.Id);

            Map(x => x.Username).CustomType<string>().Access.CamelCaseField(Prefix.Underscore);

            References(Reveal.Member<Account, Client>("Client"))
                .Cascade
                .SaveUpdate();
        }
    } // Rest of class removed

// AccountRepository.cs
        public Account GetWithClientByUsername(string username)
        {
            Account ac = null;
            Client cl = null;
            var account =  _session.QueryOver<Account>(() => ac)
                .JoinAlias(() => ac.Client, () => cl)
                .Where(() => ac.Username.Value == username)
                .SingleOrDefault<Account>();
            return account;
        }

// Username.cs
    public class Username : ValueObject<Username>
    {
        public string Value { get; }

        private Username() { }

        private Username(string value)
        {
            Value = value;
        }

        public static Result<Username> Create(string username)
        {
            username = (username ?? string.Empty).Trim();

            if (username.Length == 0)
                return Result.Fail<Username>("Username is invalid");

            return Result.Ok(new Username(username));
        }

        public static implicit operator string(Username username)
        {
            return username.Value;
        }

        public static explicit operator Username(string username)
        {
            return Create(username).Value;
        }

        protected override bool EqualsCore(Username other)
        {
            return other.Value.Equals(Value);
        }

        protected override int GetHashCodeCore()
        {
            return Value.GetHashCode();
        }
    }

NHibernate的查詢對象不能支持值對象。 嘗試使用hql,它確實支持此類映射。

string query = @"
    from Account a inner join fetch a.Client c
    where a.Username = :userName";

IList<Subscription> subscriptions = _session.CreateQuery(query)
    .SetParameter("userName", username)
    .List<Subscription>();

更多信息: https : //nhibernate.info/doc/nhibernate-reference/queryhql.html

似乎組件映射非常適合此類值對象。

public class UsernameMap : ComponentMap<Username>
{
    public UsernameMap()
    {
        Map(x => x.Value).Access.CamelCaseField(Prefix.Underscore);
    }
}

public class AccountMap : ClassMap<Account>
{
    public AccountMap()
    {
        //Use Component instead of Map for all Username mappings
        Component(x => x.Username);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM