OrderBy using RavenDB-an exception - linq

I use Raven Db in my project. Im trying to order list like below:
list.OrderByDescending(x => x.Supporters.Sum(y=>y.Tokens));
And i got an exception like this:
{"Unable to cast object of type 'System.Linq.Expressions.MethodCallExpressionN' to type 'System.Linq.Expressions.MemberExpression'."}
Model looks as below:
public class Idea
{
(...)
public IList<IdeaSupporter> Supporters { get; set; }
}
public class IdeaSupporter
{
(...)
public int Tokens { get; set; }
}
What do i wrong?
Thanks for any help.

You cannot sort on a computation, but you can define an index like this:
from idea in docs.Ideas
select new
{
SumOfSupportersTokens = idea.Supporters.Sum(x=>x.Tokens)
}
And then sort on SumOfSupportersTokens

Related

Graphql-Mutation : Schema Exception

I am trying to implement GraphQL -mutation using HotChocolate. But there is some issue with the schema (https://localhost:1234/graphql?sdl) and I am getting the unhandled exception:
The schema builder was unable to identify the query type of the schema. Either specify which type is the query type or set the schema builder to non-strict validation mode.
SchemaException: For more details look at the Errors property. 1. The schema builder was unable to identify the query type of the schema. Either specify which type is the query type or set the schema builder to non-strict validation mode.
My mutation code:
using HotChocolate
public class Book
{
public int Id { get; set; }
[GraphQLNonNullType]
public string Title { get; set; }
public int Pages { get; set; }
public int Chapters { get; set; }
}
public class Mutation
{
public async Task<Book> Book(string title, int pages, string author, int chapters)
{
var book = new Book
{
Title = title,
Chapters = chapters,
Pages = pages,
};
return book;
}
}
I have added the following in the API startup.cs file
public void ConfigureServices(IServiceCollection services)
{
services.AddGraphQLServer().AddMutationType<Mutation>();
}
You can try this:
public void ConfigureServices(IServiceCollection services)
{
services.AddGraphQLServer()
.ConfigureSchema(sb => sb.ModifyOptions(opts => opts.StrictValidation = false))
.AddMutationType<Mutation>();
}
This seems to happen when you register only a mutation type. The error goes away if you also register a query type.
So you could add the following to your code
public class Query
{
public string HelloWorld()
{
return "Hello, from GraphQL!";
}
}
And register it in your services:
public void ConfigureServices(IServiceCollection services)
{
services.AddGraphQLServer()
.AddMutationType<Mutation>()
.AddQueryType<Query>();
}
Obviously this isnt an ideal solution, as it's possible that you intend fr your API to only have mutations (although that's probably unlikely). If, like me, your API will support both queries and mutations but you just started building the mutations, you could add this query in as a place holder for now.

swagger swashbuckle does not support nested class as action method parameter

I am using asp.net 5
I have two model class, which are nested, both of the inner class are named Command
public class EditModel
{
public class Command
{
public int Id { get; set; }
public string Info { get; set; }
}
}
and
public class CreateModel
{
public class Command
{
public int Id { get; set; }
public string Info { get; set; }
}
}
In my Controller class has two methods
[HttpPost]
public IActionResult PutData(CreateModel.Command model)
{
return Ok();
}
[HttpPut]
public IActionResult PostData(EditModel.Command model)
{
return Ok();
}
Since for both Put and Post's query I am using nested class both name Command, Swagger will return the following error
An unhandled exception has occurred while executing the request.
Swashbuckle.AspNetCore.SwaggerGen.SwaggerGeneratorException: Conflicting method/path combination "PUT Test" for actions -
TestSwagger.Controllers.TestController.PutData
(TestSwagger),TestSwagger.Controllers.TestController.PostData
(TestSwagger). Actions require a unique method/path combination for
Swagger/OpenAPI 3.0. Use ConflictingActionsResolver as a workaround
at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.GenerateOperations(IEnumerable1 apiDescriptions, SchemaRepository schemaRepository) at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.GeneratePaths(IEnumerable1
apiDescriptions, SchemaRepository schemaRepository)
at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.GetSwagger(String
documentName, String host, String basePath)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext
httpContext, ISwaggerProvider swaggerProvider)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext
context)
Swagger will work, if I change one of the Command model name to something different.
Yet, I believe this nested class model name is legit and should work with swagger also. If there a way to work around this. Thanks
By adding c.CustomSchemaIds(x => x.FullName);
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "TestSwagger", Version = "v1" });
c.CustomSchemaIds(x => x.FullName);
});
solved the schemaId conflict. Thanks to this question

Confusion over MVC3 Code First / Repositories

Please can someone help me because I am getting confused.
I have an Entity like this:
public class Code
{
public int ID { get; set; }
public int UserID { get; set; }
public string CodeText { get; set; }
}
and an Interface like this:
public interface ICodeRepository
{
IQueryable<Code> Codes { get; }
void AddCode(Code code);
void RemoveCode(Code code);
Code GetCodeById(int id);
}
and a Repository like this:
public class SQLCodeRepository : ICodeRepository
{
private EFSQLContext context;
public SQLCodeRepository()
{
context = new EFSQLContext();
}
public IQueryable<Code> Codes
{
get { return context.Codes; }
}
public void AddCode(Code code)
{
context.Codes.Add(code);
context.SaveChanges();
}
public void RemoveCode(Code code)
{
context.Codes.Remove(code);
context.SaveChanges();
}
public Code GetCodeById(int id)
{
return context.Codes.Where(x => x.ID == id).FirstOrDefault();
}
}
and a Context like this:
public class EFSQLContext : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Code> Codes { get; set; }
public DbSet<PortfolioUser> PortfolioUsers { get; set; }
}
If I declare my controller like this:
public class SearchController : Controller
{
private ICodeRepository cRepo;
public SearchController(ICodeRepository codeRepository)
{
cRepo = codeRepository;
}
}
and then try to do cRepo.GetCodeById(1) nothing happens. But if I declare private ICodeRepository rep = new SQLCodeRepository and then call rep.GetCodeById(1) I can see the method in the Repository being called.
What am I doing wrong?
It looks like from the constructor signature, you are going to be doing some dependency injection. The step you are missing is to set up a DI container using a tool like Castle Windsor. You then configure the MVC resolver to use the DI container to give you the correct implementation of ICodeRepository.
See this
You'll need to create a resolver that implements IDependencyResolver and IDependencyScope and a controller factory that inheritsDefaultControllerFactory
Once you have those you can do something like the following:
MyContainer container; // this needs to be a class level member of the asax
var configuration = GlobalConfiguration.Configuration;
container = new MyContainer() // may need additional stuff here depending on DI tool used
configuration.DependencyResolver = new MyDependancyResolver(container);
var mvcControllerFactory = new MyFactory(container.Kernel);
ControllerBuilder.Current.SetControllerFactory(mvcControllerFactory);
You would call the above code from the asax Application_Start()
See this answer for more specifics on using Ninject and MVC3

How to convert ObjectSet from Entities to IEnumerable of Models?

I am building a test application using MVC3, Razor, and Entity Framework 4.1 with a schema-first approach (as apposed to a code-first approach), in a repository pattern. I would like to avoid accessing data objects in my view, and access a model instead, but I am having a problem. As far as I can tell, the data objects are being returned from the data layer as ObjectSet, but my View needs IEnumerable, and I don't know how to cast one to the other.
Here is some code, to help clarify.
Model ...
namespace TestSolution.Models
{
public class ProjectModel
{
[HiddenInput]
public int Id { get; set; }
[Required]
[StringLength(255, ErrorMessage = "The name cannot be more than 255 characters long.")]
[Display(Name = "Name")]
public string Name { get; set; }
[Required]
[Display(Name = "Description")]
public string Description { get; set; }
}
}
Repository ...
public IQueryable<ProjectModel> GetProjects()
{
return Db.Project;
}
Entities ...
public ObjectSet<Project> Project
{
get
{
if ((_Project == null))
{
_Project = base.CreateObjectSet<Project>("Project");
}
return _Project;
}
}
Controller ...
public ActionResult Index()
{
IEnumerable<TestSolution.Models.ProjectModel> model = _projectRepository.GetProjects();
return View(model);
}
View ...
#model IEnumerable<TestSolution.Models.ProjectModel>
Error I am getting when building ...
Cannot implicitly convert type 'System.Data.Objects.ObjectSet<TestSolution.Project>' to 'System.Linq.IQueryable<TestSolution.Models.ProjectModel>'. An explicit conversion exists (are you missing a cast?)
Does this question make sense? I am just not sure where go from here ... any advise you guys can give me would be awesome. :)
EDIT: I was able to solve this with Kyle's suggestion by changing my Repository code to ...
public IQueryable<ProjectModel> GetProjects()
{
return Db.Project.Select(i => new ProjectModel() { Id = i.Id, Name = i.Name, Description = i.Description });
}
The problem isn't converting from ObjectSet<T> to IEnumerable<T> (ObjectSet<T> implements IEnumerable<T>).
The problem is converting from TestSolution.Project to TestSolution.Models.ProjectModel. You will need to write some conversion code, maybe something similar to the below:
model.Select(i => new ProjectModel() { /* Set properties here. */ });

How to get an array of members of an array

Suppose I have a class
public class Foo
{
public Bar Bar { get; set; }
}
Then I have another class
public class Gloop
{
public List<Foo> Foos { get; set; }
}
What's the easiest way to get a List<Bar> of Foo.Bars?
I'm using C# 4.0 and can use Linq if that is the best choice.
UPDATE:
Just for a little dose of reality, the reason for this is that I have a Windows Service class that contains an inner ServiceBase derived class as a property. So I end up with code like this:
public class Service
{
public ServiceBase InnerService { get; set; }
}
public class ServiceHost
{
private List<Service> services = new List<Service>();
static void Main()
{
// code to add services to the list
ServiceBase.Run(services.Select(service => service.InnerService).ToArray());
}
}
This one's simple, if I've understood you rightly:
List<Foo> foos = gloop.Foos; // Or wherever you're getting it from
List<Bar> bars = foos.Select(foo => foo.Bar)
.ToList();
If you only need an IEnumerable<Bar> you can just use Select without the call to ToList. Of course you don't need the foos local variable if you don't want it - you can just have a single statement. I've only separated them out in case you've got an existing List<Foo> or Foo[] (you mention arrays in your subject line).
var bars = gloop.Foos.Select(foo => foo.Bar);

Resources