CosmosDbClient - ошибка при преобразовании значения в тип System.Guid - PullRequest
0 голосов
/ 24 марта 2020

В приведенном ниже коде есть две проблемы:

  • фильтрация по «Статусу» возвращает пустую коллекцию, хотя в базе данных явно есть элементы
  • при попытке извлечь все элементы, код завершается с ошибкой «Ошибка преобразования значения« Предложение »в тип« System.Guid ». Путь» Documents [0] .id ', строка 1, позиция 203. ».

Пожалуйста, помогите мне исправить их.

// Referenced NuGet packages:
// - Microsoft.EntityFrameworkCore 3.1.2
// - Microsoft.EntityFrameworkCore.Cosmos 3.1.2
// - Microsoft.Extensions.DependencyInjection 3.1.2

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Azure.Cosmos.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;

namespace CosmosDbDemo
{
#region CosmosDb parameters
// Define here your CosmosDb database connection
class CosmosDbParameters
{
    public const string AccountEndPoint = "{YOUR-ACCOUNT-ENDPOINT-HERE}";
    public const string AccountKey = "{YOUR-ACCOUNT-KEY-HERE}";
    public const string DbName = "DemoIssues";
    public const string DbContainer = "Offers";
}
#endregion


class Program
{
    static async Task Main( string[] args )
    {
        // Configure services
        var serviceProvider =
            new ServiceCollection()
            .AddDbContext<OfferContext>( 
                options => options.UseCosmos(  CosmosDbParameters.AccountEndPoint, CosmosDbParameters.AccountKey, CosmosDbParameters.DbName ) )
            .BuildServiceProvider();

        using var ctx = serviceProvider.GetService<OfferContext>();

        // Ensure database has been properly created.
        ctx.Database.EnsureCreated();

        // Insert some items. A future query will try to retrieve only some of them.
        await AddItems( ctx );

        // Bypass EF. This one returns an empty results set.
        await QueryUsingCosmosClient( ctx );

        // Bypass EF. Simply try to return all available items.
        // Fails with error 
        // "Error converting value "Offer" to type 'System.Guid'. Path 'Documents[0].id', line 1, position 203."
        await QueryUsingCosmosClient2( ctx );
    }

    private static async Task QueryUsingCosmosClient( OfferContext ctx )
    {
        var cosmosClient = ctx.Database.GetCosmosClient();
        var db = cosmosClient.GetDatabase(CosmosDbParameters.DbName );
        var container = db.GetContainer( CosmosDbParameters.DbContainer );
        var queryable = container.GetItemLinqQueryable<Offer>();
        var query = queryable.Where( _ => _.Status == OfferStatus.Created );
        var iterator = query.ToFeedIterator();
        var offers = new List<Offer>();
        while( iterator.HasMoreResults )
        {
            var buffer = await iterator.ReadNextAsync();
            offers.AddRange( buffer );
        }

        Console.WriteLine( $"QueryUsingCosmosClient returned {offers.Count} results" );
    }

    private static async Task QueryUsingCosmosClient2( OfferContext ctx )
    {
        try
        {
            var cosmosClient = ctx.Database.GetCosmosClient();
            var db = cosmosClient.GetDatabase(CosmosDbParameters.DbName );
            var container = db.GetContainer( CosmosDbParameters.DbContainer );
            var queryable = container.GetItemLinqQueryable<Offer>();
            var query = queryable.Where( _ => true );
            var iterator = query.ToFeedIterator();
            var offers = new List<Offer>();
            while( iterator.HasMoreResults )
            {
                var buffer = await iterator.ReadNextAsync();
                offers.AddRange( buffer );
            }

            Console.WriteLine( $"QueryUsingCosmosClient2 returned {offers.Count} results" );
        }
        catch( Exception ex )
        {
            Console.WriteLine( ex );
        }

    }

    private static async Task AddItems( OfferContext ctx )
    {
        var offer = BuildOffer( "Acme Offer 1", 14 );
        ctx.Add( offer );
        offer = BuildOffer( "Acme Offer 2", 30 );
        ctx.Add( offer );
        offer = BuildOffer( "Coyote Ugly Super Offer 1", 25 );
        ctx.Add( offer );
        offer = BuildOffer( "Sloth Supercars Offer 14", 10 );
        ctx.Add( offer );
        await ctx.SaveChangesAsync();
    }

    private static Offer BuildOffer( string name, int valabilityInDays )
    {
        var result = new Offer
        {
            Id = Guid.NewGuid(),
            Name = name,
            ExpirationDateUtc = DateTime.UtcNow.Date.AddDays( valabilityInDays ),
            Status = OfferStatus.Created
        };

        return result;
    }
}

class Offer
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public DateTime ExpirationDateUtc { get; set; }
    public OfferStatus Status { get; set; }
}

enum OfferStatus
{
    Created = 0,
    Approved = 1,
    Accepted = 2,
    Declined = 3
}

class OfferContext : DbContext
{
    public OfferContext( DbContextOptions<OfferContext> options ) : base( options )
    {

    }

    public DbSet<Offer> Offers { get; set; }


    protected override void OnModelCreating( ModelBuilder modelBuilder )
    {
        modelBuilder.HasDefaultContainer( CosmosDbParameters.DbContainer );
        modelBuilder.Entity<Offer>().HasPartitionKey( _ => _.Id );
        modelBuilder.Entity<Offer>().Property( _ => _.Id )
                .HasConversion( _ => _.ToString( "B" ), _ => Guid.Parse( _ ) );
        modelBuilder.Entity<Offer>().Property( _ => _.Status )
                .HasConversion( _ => _.ToString(), _ => (OfferStatus)Enum.Parse( typeof( OfferStatus ), _ ) );
    }
}

}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...