>

Azure 코스모스 문서 DB에서 개체를 쿼리하려고했습니다. UserRepository  소비자가 자신의 User 를 정의 할 수 있도록 일반화   IUser 를 구현하는 한 저장소를 사용할 때 객체  인터페이스.

UserRepository는 다음과 같습니다

public class UserRepository<T> : IUserRepository<T> where T : class, IUser
{
    private readonly CosmosDbOptions _cosmosDBOptions;
    private readonly DocumentDbHelper _documentDBHelper;
    public UserRepository(
        IOptions<CosmosDbOptions> cosmosDBOptions,
        DocumentDbHelper documentDBHelper)
    {
        _cosmosDBOptions = cosmosDBOptions.Value;
        _documentDBHelper = documentDBHelper;
    }
    public T GetUserByEmail(string email)
    {
        if (string.IsNullOrWhiteSpace(email))
            return default(T);
        var user = _documentDBHelper
            .GetItemsAsync<T>(u => ((T)u).Email == email, _cosmosDBOptions.DocumentDb.UserCollection, email)
            .Result
            .OrderBy(u => u.Modified)
            .FirstOrDefault();
        return user;
    }
    ...
}

DocumentDbHelper의 모습은 다음과 같습니다

public class DocumentDbHelper
{
    private readonly DocumentClient _client;
    private readonly DocumentDbOptions _documentDBOptions;
    public DocumentDbHelper(IOptions<CosmosDbOptions> documentDBOptions)
    {
        _cosmosDBOptions = documentDBOptions.Value.DocumentDb;
        var serializerSettings = new JsonSerializerSettings
        {
            DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind,
            DateFormatHandling = DateFormatHandling.IsoDateFormat,
            DateParseHandling = DateParseHandling.DateTimeOffset
        };
        _client = new DocumentClient(
            new Uri(_cosmosDBOptions.Endpoint), _cosmosDBOptions.AuthKey, serializerSettings);
    }
    public async Task<IEnumerable<T>> GetItemsAsync<T>(
        Expression<Func<T, bool>> predicate, string collectionId, string partitionKey)
    {
        var query = _client.CreateDocumentQuery<T>(
            UriFactory.CreateDocumentCollectionUri(_cosmosDBOptions.DatabaseId, collectionId),
            new FeedOptions { PartitionKey = new PartitionKey(partitionKey) })
        .Where(predicate)
        .AsDocumentQuery();
        var results = new List<T>();
        while (query.HasMoreResults)
        {
            results.AddRange(await query.ExecuteNextAsync<T>());
        }
        return results;
    }
    ...
}

다음은 UserRepository 사용 방법입니다

public class UsersController : Controller
{
    private readonly IUserRepository<User> _userRepository;
    public UsersController(IUserRepository<User> userRepository)
    {
        _userRepository = userRepository;
    }
    public IActionResult Get(string email)
    {
        var user = _userRepository.GetUserByEmail(email);
        return Ok(user);
    }
}

다시 명확히하기 위해 UserRepository는 일반화되어 다른 소비자가 이와 같이 할 수 있습니다.

public class Users2Controller : Controller
{
    private readonly IUserRepository<User2> _userRepository;
    public Users2Controller(IUserRepository<User2> userRepository)
    {
        _userRepository = userRepository;
    }
    public IActionResult Get(string email)
    {
        var user = _userRepository.GetUserByEmail(email);
        return Ok(user);
    }
}

문제는 UsersController.Get 를 실행할 때입니다  그리고 그것은 GetItemsAsync 에 도달  와이즈 비츠 이 메소드는 DocumentDbHelper 를 리턴합니다. 컨트롤러 작업에 전달 된 유효한 이메일 주소를 가진 개체가 있더라도

그러나 pyzwyz에서 UserRepository의 제약 조건을 변경하면   null 로  아래처럼

where T : class, IUser

개체가 성공적으로 검색되었습니다.

이 이유는 무엇입니까? 인터페이스 제약 조건을 통해이 작업을 수행 할 수 있습니까?

where T : User
  • 답변 # 1

    아래에 언급 된대로 사용하려고하면 작동합니다.

    public class UserRepository<T> : IUserRepository<T> where T :  IUser
    
    

  • 답변 # 2

    근본 원인을 찾았습니다.

    User 의 스 니펫은 다음과 같습니다.  수업 :

    public class User : IUser
    {
        [JsonProperty("id")]
        public string DocumentId { get; set; } = "";
        [JsonProperty("created")]
        public DateTimeOffset Created { get; set; }
        [JsonProperty("modified")]
        public DateTimeOffset Modified { get; set; }
        [JsonProperty("email")]
        public string Email { get; set; }
        ...
    }
    
    

    그리고 여기 IUser 가 있습니다  보는 데 사용되는 인터페이스 :

    public interface IUser
    {
        string DocumentId { get; set; }
        DateTimeOffset Created { get; set; }
        DateTimeOffset Modified { get; set; }
        string Email { get; set; }
        ...
    }
    
    

    문제는이 https://github.com/Azure/azure-documentdb-dotnet/issues/317과 관련이 있습니다. JsonProperty 를 추가하면   IUser 의 속성  아래와 같은 인터페이스 소품 :

    public interface IUser
    {
        [JsonProperty("id")]
        string DocumentId { get; set; }
        [JsonProperty("created")]
        DateTimeOffset Created { get; set; }
        [JsonProperty("modified")]
        DateTimeOffset Modified { get; set; }
        [JsonProperty("email")]
        string Email { get; set; }
        ...
    }
    
    

    완벽하게 작동합니다.

관련 자료

  • 이전 sql - 시간 범위 간의 필터 및 그룹 결과
  • 다음 vue.js - vue는 메소드를 통해 데이터를 정의 할 수 있습니까?