В приведенном ниже коде есть две проблемы:
- фильтрация по «Статусу» возвращает пустую коллекцию, хотя в базе данных явно есть элементы
- при попытке извлечь все элементы, код завершается с ошибкой «Ошибка преобразования значения« Предложение »в тип« 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 ), _ ) );
}
}
}