5

Linq to Entities クエリからこれらの型のいずれかを返すことができないため、リストを返すことに固執しています。

DB 呼び出し (別の WCF サービスまたは DLL 内) から戻ると、dbcontext 接続が閉じているため、コントローラーのコードが失敗します。

次のコードに注意してください。IEnumerable と IQueryable の両方について、上記の説明により、データは返されません。

MVC コントローラーのメソッド

// Controller
IEnumerable<ProjectDescription> projectDdl = db.GetProjectDropDownList().AsEnumerable();
// Error coming back because dbcontext connection was closed.
ViewBag.ProjectsCust = new SelectList(projectDdl, "ProjectId", "Name");

WCF サービスまたは DLL のメソッド

// WCF Service or DLL 
public IEnumerable<ProjectDescription> GetProjectDropDownList()
{
    try
    {
        //IQueryable<ProjectDescription> project = null;

        using (YeagerTechEntities DbContext = new YeagerTechEntities())
        {
            DbContext.Configuration.ProxyCreationEnabled = false;
            DbContext.Database.Connection.Open();

            IEnumerable<ProjectDescription> project = DbContext.Projects.Select(s =>
                new ProjectDescription()
                {
                    ProjectID = s.ProjectID,
                    Description = s.Description
                }
            );


            return project;
        }


    }
    catch (Exception ex)
    {
        throw ex;
    }
}

DB呼び出しの前に次のDbContextインスタンスを確立しようとしましたが、実際にはDbContextをDBメソッドに渡そうとしても機能しませんでした。

コントローラ:

DbContext = new YeagerTechEntities();
IEnumerable<ProjectDescription> projectDdl = db.GetProjectDropDownList(DbContext).AsEnumerable();
ViewBag.ProjectsCust = new SelectList(projectDdl, "ProjectId", "Name");

DbContext.Dispose();

DB メソッド:

public IEnumerable<ProjectDescription> GetProjectDropDownList(YeagerTechEntities DbContext)
{
    try
    {
        //IQueryable<ProjectDescription> project = null;


            DbContext.Configuration.ProxyCreationEnabled = false;
            DbContext.Database.Connection.Open();

            IEnumerable<ProjectDescription> project = DbContext.Projects.Select(s =>
                new ProjectDescription()
                {
                    ProjectID = s.ProjectID,
                    Description = s.Description
                }
            );


            return project;
        }


    catch (Exception ex)
    {
        throw ex;
    }
}

List を使用する以外に機能した唯一のことは、実際に DB メソッドを Controller 内に配置することでした。これは明らかに良い習慣ではありません。

正常に機能するリスト規則は次のとおりです。

コントローラ:

IEnumerable<ProjectDescription> projectDdl = db.GetProjectDropDownList();
                ViewBag.ProjectsCust = new SelectList(projectDdl, "ProjectId", "Name");

DB メソッド:

public List<ProjectDescription> GetProjectDropDownList()
{
    try
    {
        using (YeagerTechEntities DbContext = new YeagerTechEntities())
        {
            DbContext.Configuration.ProxyCreationEnabled = false;
            DbContext.Database.Connection.Open();

            IEnumerable<ProjectDescription> project = DbContext.Projects.Select(s =>
                new ProjectDescription()
                {
                    ProjectID = s.ProjectID,
                    Description = s.Description
                }
            );

            List<ProjectDescription> myProjects = new List<ProjectDescription>();

            myProjects = project.ToList();

            return myProjects;
        }
    }
    catch (Exception ex)
    {
        throw ex;
    }
}

IQueryable または IEnumerable を使用するときに正しいモデルがどうあるべきかを誰かが説明できれば、それで問題ありません。ただし、このリンクを読んだ後、リストが進むべき道であるように思われます: IEnumerable vs IQueryable for Business Logic or DAL return Types

4

2 に答える 2

2

DbContextご存知のように、データベースにクエリを実行できるようにするため、SQL 要求が SGBD に送信されたときにデータベースが有効になっている必要があります。

ここでの重要な点は、IQueryableがどのように機能するかを正確に知ることです。

IQueryable インターフェイスは IEnumerable インターフェイスを継承しているため、クエリを表す場合、そのクエリの結果を列挙できます。列挙により、IQueryable オブジェクトに関連付けられた式ツリーが実行されます。「式ツリーの実行」の定義は、クエリ プロバイダーに固有です。たとえば、式ツリーを基になるデータ ソースの適切なクエリ言語に変換する必要がある場合があります。

つまり、Linq クエリが (.ToList() または foreach で) 列挙されていない限り、クエリはデータベースに送信されません。実行は延期されます!

あなたの最初の試みでは、あなたは:

  • GetProjectDropDownListメソッドの呼び出し
  • IEnumerable「列挙」せずに(Lingクエリである)を返す
  • 廃棄するDbContext
  • ビューが生成されたときにLinqクエリを列挙していnew SelectListますが...あなたDbContextはその時点ですでに破棄されています。

同じことが2回目の試みにも当てはまります。これDbContextは少し後に破棄されますが、ビューが生成されたときにすでに破棄されています。

最後の試行でDbContextは、Linq クエリを列挙しているときにまだ生きているため、すべて正常に動作します (with project.ToList();)

私の意見では、DbContext呼び出しとインスタンスをデータ アクセス レイヤーに分離し、リストまたは単純な切断されたオブジェクトを返すことは、まったく悪い習慣ではありません。

于 2013-10-22T18:39:54.800 に答える