2

私が取り組んでいる EF 5/MVC 4 のデータベース ファースト プロジェクトがあり、アプリケーションの特定の論理機能領域 (UserManagement、CompanyManagement、InventoryManagement、OrderManagement) 用に個別の edmx ファイルを作成しました。UserProfile テーブルは、CreatedById テーブルと ModifiedById テーブルに結合するために存在するため、すべての edmx ファイルに含まれているため、実際のユーザー名を取得できます。しかし、UserProfile テーブルの各バージョンに追加のプロパティとデータ注釈を作成したくないので、追加のプロパティを追加して追加する UserManagement 領域にある UserProfile の (私が呼ぶもの) 「元のバージョン」を継承します。私のデータ注釈。わかりました、まだ私と一緒ですか?

それでは、EF 5 が (UserManagement 領域/フォルダーに) 作成する元の UserProfile クラスを次に示します。

namespace OTIS.domain.UserMgmt
{
    using System;
    using System.Collections.Generic;

    public partial class UserProfile
    {
        public UserProfile()
        {
            this.webpages_Roles = new HashSet<webpages_Roles>();
        }

        public int UserId { get; set; }
        public Nullable<int> AccountId { get; set; }
        public string UserName { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Email { get; set; }

        public virtual webpages_Membership webpages_Membership { get; set; }
        public virtual ICollection<webpages_Roles> webpages_Roles { get; set; }
    }
}

追加のプロパティを追加し、データ注釈を追加するために使用する部分クラスを次に示します。

namespace OTIS.domain.UserMgmt
{
    [MetadataType(typeof(UserProfileMD))]
    public partial class UserProfile : IEntity
    {
        public int Id
        {
            get
            {
                return this.UserId;
            }
        }

        public string FullName
        {
            get
            {
                return this.FirstName + " " + this.LastName;
            }
        }

        public string EntityDescription
        {
            get
            {
                return this.FullName;
            }
        }

        public class UserProfileMD
        {
            public int UserId { get; set; }

            [Required]
            [Display(Name = "User Name")]
            public string UserName { get; set; }

            [Required]
            [Display(Name = "First Name")]
            public string FirstName { get; set; }

            [Required]
            [Display(Name = "Last Name")]
            public string LastName { get; set; }

            [Display(Name = "Name")]
            public string FullName { get; set; }

            [Display(Name = "Email")]
            public string Email { get; set; }

        }
    }
}

現在、InventoryMgmt edmx にあるバージョンの UserProfile を使用しているため、同じ名前の部分クラスを作成し、上記から継承しました。

namespace OTIS.domain.InventoryMgmt
{
    [MetadataType(typeof(OTIS.domain.UserMgmt.UserProfile.UserProfileMD))]
    public partial class UserProfileInvnMgmt : UserProfile
    {

    }
}

現在、InventoryMgmt edmx にも PO ヘッダーがあります。EF によって生成されたクラスを次に示します (CreatedById への外部キー テーブルである UserProfileInvnMgmt UserProfile を参照することに注意してください)。

namespace OTIS.domain.InventoryMgmt
{
    using System;
    using System.Collections.Generic;

    public partial class POHeader
    {
        public POHeader()
        {
            this.PODetails = new HashSet<PODetail>();
        }

        public int Id { get; set; }
        public int FacilityId { get; set; }
        public int VendorId { get; set; }
        public int StatusId { get; set; }
        public string Notes { get; set; }
        public int CreatedById { get; set; }
        public System.DateTime CreatedOn { get; set; }
        public int ModifiedById { get; set; }
        public System.DateTime ModifiedOn { get; set; }

        public virtual ICollection<PODetail> PODetails { get; set; }
        public virtual Vendor Vendor { get; set; }
        public virtual POHeaderStatus POHeaderStatus { get; set; }
        public virtual UserProfileInvnMgmt UserProfile { get; set; }
        public virtual UserProfileInvnMgmt UserProfile1 { get; set; }
    }
}

これで、POHeader クラス エンティティをビュー モデルに変換するメソッドができました。設計時に、POHeader.UserProfile.FullName をビュー モデル プロパティ OrderedBy に割り当てることができます。

public IEnumerable<POHeadersListViewModel> ConvertClassToViewModel(IEnumerable<POHeader> purchaseOrders)
    {
        IEnumerable<POHeadersListViewModel> poGrid =
            from l in purchaseOrders.ToList()
            select new POHeadersListViewModel()
            {
                Id = l.Id,
                VendorName = l.Vendor.VendorName,
                OrderedBy = l.UserProfile.FullName,
                OrderDate = l.CreatedOn,
                Status = l.POHeaderStatus.DisplayName
                //OwnerName = l.Customer == null ? "" : l.Customer.CustomerName
            };

        return poGrid;
    }

ただし、このコードを実行すると、OrderedBy に値が割り当てられず、デバッグ中に IEnumerable purchaseOrders 変数を展開すると UserProfile が表示されますが、展開すると FullName プロパティは表示されず、FirstName と LastName は表示されません。が設定されています。ビュー モデルの結果の値または OrderBy は単一のスペースであり、FullName プロパティが返されているように見えますが、その FirstName と LastName は null であり、FullName は FirstName プロパティと LastName プロパティを区切るはずの空白を返すだけです。 、つまり

public string FullName
    {
        get
        {
            return this.FirstName + " " + this.LastName;
        }
    }

ただし、これを行う場合は次のことに注意してください。

OrderedBy = l.UserProfile.FirstName + " " + l.UserProfile.LastName,

これは機能するため、FirstName と LastName は null ではありません。FullName が正しく返されない理由についてのアイデアはありますか? 一般に、UserProfile の複数のバージョンを処理するための最良の方法は何ですか?

4

1 に答える 1

0

public partial class UserProfile : IEntityこれが問題かどうかはわかりませんが、部分クラスはauto-genクラスが拡張しないIEntityを拡張します。これらは完全に一致する必要があると思いますか、それともC#でそれが可能ですか?

更新あなたが問題にしているのは、linqクエリで派生/計算されたプロパティを使用しようとしていることだと思います。EFを使用してこれをデータベースにマッピングし直すことを検討すると、処理/変換できるものではありません。この議論は関連しているようです:LINQステートメント内で部分的なクラスプロパティを使用する

于 2013-01-16T22:35:00.573 に答える