2016-04-17 18 views
0

このEFコードの最初のエンティティの部分クラスです。DbContext.Database.SqlQuery INNER JOINを持つ<T>は、基本クラスのプロパティ値を設定しません。

public partial class Report 
{ 
    public Guid ReportId { get; set; } 
    public string Status { get; set; } 
    public DateTime SurveyDate { get; set; } 
} 

そして、この部分的な拡張です。

public partial class Report : SyncObject 
{ 
    public override string ObjectId 
    { 
     get { return ReportId.ToString(); } 
     set { ReportId = Guid.Parse(value); } 
    } 
} 

SyncObject基本クラス。

public class SyncObject : ISyncObject 
{ 
    public virtual string ObjectId { get; set; } 
    public long VersionNumber { get; set; } 
    public DateTime CreateDateTime { get; set; } 
    public DateTime LastUpdateDateTime { get; set; } 
    public bool IsDeleted { get; set; } 
    public virtual string CorrelationId { get; set; } 
} 

EF構成クラスでは、SyncObjectプロパティはテーブルの一部ではないため、無視されます。我々は2つのデータベースのテーブルを持っている

public partial class ReportConfiguration : EntityTypeConfiguration<Report> 
{ 
    public ReportConfiguration() 
     : this("Wind") 
    { 
    } 

    public ReportConfiguration(string schema) 
    { 
     ToTable(schema + ".Reports"); 
     HasKey(x => x.ReportId); 

     Property(x => x.ReportId).HasColumnName("ReportId").IsRequired().HasColumnType("uniqueidentifier").HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.None); 
     Property(x => x.Status).HasColumnName("Status").IsRequired().IsUnicode(false).HasColumnType("varchar").HasMaxLength(50); 
     Property(x => x.SurveyDate).HasColumnName("SurveyDate").IsRequired().HasColumnType("date"); 
     Ignore(x => x.CorrelationId); 
     Ignore(x => x.ObjectId); 
     Ignore(x => x.CreateDateTime); 
     Ignore(x => x.IsDeleted); 
     Ignore(x => x.LastUpdateDateTime); 
     Ignore(x => x.VersionNumber); 
    } 
} 

、SyncMetadataで外部キーを使用したレポートとSyncMetadata、それは別のPKデータ型とDBのシンプルさとサポートのテーブルのためにこの方法を必要としています。

私はDbContext.Database.SqlQuery<T>("QUERY").ToListAsync()を使用するので、EFコンテキストトラッキングは気にしません。

クエリは2つのテーブル間の結合を行い、すべてのフィールドを返します。

SELECT ReportId 
     ,Status 
     ,SurveyDate 
     ,S.CorrelationId 
     ,S.ObjectId 
     ,S.VersionNumber 
     ,S.CreateDateTime 
     ,S.LastUpdateDateTime 
     ,S.IsDeleted 
    FROM Reports R 
    INNER JOIN SyncMetadata S 
    ON R.ReportId=S.ObjectId 

SQL Server Management Studioのは、このクエリで素晴らしい作品、私はテーブルから参加したすべてのフィールドで必要なレコードを取得するが、問題がのSQLQueryがSyncObject基本クラスにSyncMetadataフィールドを追加していないということですプロパティ。

+0

Domainクラスではなく.SqlQueryを使用してみましたが、代わりに継承を持つクラスセットを別にしましたか?これは、クエリにReportConfigurationを使用できるように感じますが、私はこのアサーションを今すぐチェックすることはできません。 –

+0

@raderickあなたは正しく、クラスをEFドメインエンティティから自分のデータ転送オブジェクトクラスに変更し、完璧に機能しました。アイデアをお寄せいただきありがとうございます。この場合、Automapperは必要ありません。回答を投稿すると解決済みとマークします。 –

答えて

1

テストの必要がある。このため、複数の可能な理由があるかもしれません:sqlqueryのが実行されたときに

  1. エンティティタイプの構成が使用されています。

エンティティフレームワークCodePlexによると、これは当てはまりません:http://entityframework.codeplex.com/workitem/233?PendingVoteId=233

SqlQueryメソッドは、属性を使用して適用されるマッピングを含む を考慮に入れないように設計されています。オブジェクト内のプロパティ名を持つ結果の列名を と単純に一致させます。 列名が一致しない場合、列エイリアス (SQL ServerのASキーワード)を使用して、結果の列の名前を変更する必要があります。

これは、EF 6の最新バージョンについても言えます。

  1. 継承はSqlQueryメソッドでは処理されません。

ドメインクラスではなく、継承を持つクラスのセットを別々にしてみてください。正常に動作する場合は別の場所に問題があります。うまくいけば、これはおそらくあなたのための解決策かもしれません。

あなたはいつものソースをダウンロードして、解決策を得るためにそれらを分析することができます http://entityframework.codeplex.com/SourceControl/latest ちょうど見にステップによって代わりにNuGetのパッケージおよびデバッグ段階でそれをプラグイン、どのような場所にエラーが発生します。

私は、SqlQueryからDTOオブジェクトを取得することを強くお勧めします。ここでは副作用が最小限に抑えられます。非トラッキングドメインエンティティクエリの場合、あなたに該当する場合、.AsNoTracking()でLinqクエリを使用することをお勧めします。

関連する問題