16

単一のレコードを取得しようとしているときに、Azure DocumentDb ストレージ アカウントにクエリを実行しようとすると問題が発生します。これは私の WebAPI コードです:

// Controller...
public AccountController : ApiController {
    // other actions...

    [HttpGet]
    [Route("Profile")]
    public HttpResponseMessage Profile()
    {
        var userId = User.Identity.GetUserId();
        var rep = new DocumentRepository<UserDetail>();
        var profile = rep.FindById(userId);

        if (profile == null)
            return Request.CreateErrorResponse(HttpStatusCode.NotFound, "Profile not found");

        return Request.CreateResponse(HttpStatusCode.OK, profile);
    }
}

// Repository
public class DocumentRepository<TEntity> : IDocumentRepository<TEntity> where TEntity : IIdentifiableEntity
{
    private static DocumentClient _client;
    private static string _databaseName;
    private static string _documentsLink;
    private static string _selfLink;

    public DocumentRepository()
    {
        _client = new DocumentClient(new Uri(ConfigurationManager.AppSettings["DocumentDbEndpointUrl"]), ConfigurationManager.AppSettings["DocumentDbAuthKey"]);
        _databaseName = ConfigurationManager.AppSettings["DocumentDbDatabaseName"];
        var _database = ReadOrCreateDatabase();

        var collection = InitialiseCollection(_database.SelfLink, EntityName);
        _documentsLink = collection.DocumentsLink;
        _selfLink = collection.SelfLink;
    }

    // other methods...

    public TEntity FindById(string id)
    {
        return _client.CreateDocumentQuery<TEntity>(_documentsLink).SingleOrDefault(u => u.Id.ToString() == id);
    }
}

このFindById方法により、次の問題が発生します。

タイプ 'Microsoft.Azure.Documents.Linq.DocumentQueryException' の例外が Microsoft.Azure.Documents.Client.dll で発生しましたが、ユーザー コードで処理されませんでした

追加情報: クエリ式が無効です。式の戻り値の型
Foo.Models.DocumentDbEntities.UserDetail はサポートされていません。クエリは IEnumerable に評価される必要があります。

このエラーの意味や修正方法がわかりません。このメソッドはorレコードを返すため、 IEnumerableor の子孫クラスを返したくありません。句を削除して戻り値の型を anに変更すると機能しますが、これは私が望むものではありません。01SingleOrDefaultIQueryable

4

2 に答える 2

30

SingleOrDefault()LINQ プロバイダーではまだサポートされていません。

これをに変更.Where(u => u.Id.ToString() == id).AsEnumberable().FirstOrDefault();

于 2014-11-04T01:25:26.483 に答える
1

Ryan の構文が機能しなくなった理由はわかりませんが、.Where() を使用する代わりに、明示的に定義されたクエリ文字列で CreateDocumentQuery<>() オーバーロードを使用することにより、パフォーマンスに余分な影響を与えることなく回避できるはずです。 :

string query = string.Format("SELECT * FROM docs WHERE docs.id = \"{0}\"", id);
return _client.CreateDocumentQuery<TEntity>(DocumentsLink, query).AsEnumerable().FirstOrDefault();

クエリを少しいじる必要があるかもしれませんが、その形式の何かが機能するはずです。

于 2014-11-06T16:47:40.557 に答える