I recently updated our project from EF Core 2.2.6 to 6.x (along with and upgrade from .NET core 3.1 to .NET 6) and now I'm get errors like the one stated in the title whenever the query gets even a little complicated. One of those cases is when you add a GroupBy clause. Below is an example of a failing query.
_context.MyTable
.Where(a => a.Name.Contains("service"))
.GroupBy(ss => ss.IsServiceSpecific)
The entire error is:
The LINQ expression 'DbSet< MyTable >()
.Where(a => a.Name.Contains("service"))
.GroupBy(ss => ss.IsServiceSpecific)' could not be translated. Either rewrite the query in a form that can be translated, or switch
to client evaluation explicitly by inserting a call to 'AsEnumerable',
'AsAsyncEnumerable', 'ToList', or 'ToListAsync'
The setup at this MySQL::Entity Framework Core Support URL is exactly what I did (there are only two steps to set it up). My DI config looks like this:
builder.Services.AddEntityFrameworkMySQL()
.AddDbContext<MydbContext>(options =>
{
options.UseMySQL(builder.Configuration.GetConnectionString("DefaultConnection"));
});
It will execute simple queries but more complex ones always generate this error. It says to rewrite the query and force client side evaluation by using AsEnumerable or ToList but I don't want to drag all that data to the client and I expect that a simple group by can be translated and handled server side.
I did find one article that talks about this problem but I'm not getting if it's suggesting an actual solution.
This shouldn't be this hard and I feel like I'm missing something simple.
Model
internal class Post
{
public int PostId { get; set; }
public string? Title { get; set; }
public string? Content { get; set; }
public int BlogId { get; set; }
}
DBContext
internal class BloggingContext : DbContext
{
public DbSet<Post>? Posts { get; set; }
public string DbPath { get; }
public BloggingContext()
{
var path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
DbPath = $"{path}{Path.DirectorySeparatorChar}blogging.db";
}
protected override void OnConfiguring(DbContextOptionsBuilder options)
=> options.UseSqlite($"Data Source={DbPath}");
}
Main
internal class Program
{
static void Main(string[] args)
{
using (var db = new BloggingContext())
{
var posts = db.Posts.Where(s => s.Title.Contains("Hello")).GroupBy(g => g.BlogId == 1994).Select(s => new { Key = s.Key, Counts = s.Count() }).ToList();
foreach (var p in posts)
{
Console.WriteLine(p);
}
}
}
}
Conclusion: You might add Select statement after GroupBy.
I want to get the value of a MySQL variable (example: max_allowed_packet) via jdbcTemplate. is this possible? if so, how ?
In SQL, I can do SHOW VARIABLES LIKE 'max_allowed_packet'; but how to do this via JDBCTemplate ?
Here is a solution
public List<Variable> findAllVariables() {
List<Variable> result = jdbcTemplate.query("SHOW GLOBAL VARIABLES", new VariableRowMapper());
//about 630 variables
return result;
}
Variable class:
public class Variable {
private String name;
private String value;
//getters and setters
}
VariableRowMapper class:
public class VariableRowMapper implements RowMapper<Variable> {
#Override
public Variable mapRow(ResultSet resultSet, int rowNum) throws SQLException {
String name = resultSet.getString("Variable_Name");
String value = resultSet.getString("Value");
return new Variable(name, value);
}
}
hope it helps.
I was particularly interested in getting the max_allowed_packet variable from the database. This below snippet does the trick.
private int fetchMaxAllowedPacketsFromDB(JdbcTemplate jdbcTemplate) {
final String sql = "SELECT ##GLOBAL.max_allowed_packet";
Integer maxAllowedPacketsFromDB = jdbcTemplate.queryForObject(sql, Integer.class);
log.info("##GLOBAL.max_allowed_packet : {}", maxAllowedPacketsFromDB);
return maxAllowedPacketsFromDB;
}
You can look at #Ali4j 's answer for a more generic/multi-variable requirement.
Or, You can refactor the snippet above to pass in a variable as argument, if you don't need the extra work of RowMappers
I'm currently programming a Discord RPC client, which shows a preview of the Presence.
I found out, that with "https://discordapp.com/api/oauth2/applications/[appid]/assets" you get the asset id from the application and with it the image using "https://cdn.discordapp.com/app-assets/[appid]/[assetid].png". But how do i get the application name with the client id?
I have this class, which sets AppName in customStatus class
class getAppName
{
static DiscordRpcClient client;
public getAppName(string AppId)
{
client = new DiscordRpcClient(AppId);
client.Initialize();
client.OnReady += OnClientReady;
client.OnPresenceUpdate += Client_OnPresenceUpdate;
}
private void Client_OnPresenceUpdate(object sender, PresenceMessage args)
{
customStatus.AppName = (args.Name);
client.ClearPresence();
client.Dispose();
}
private void OnClientReady(object sender, ReadyMessage args)
{
client.SetPresence(new RichPresence { });
}
}
And in customStatus class:
public static string AppName { get; set; }
And:
new getAppName("AppId");
var oldName = AppName;
//this is to wait until the new appname is set
while (oldName == AppName) {}
string newAppname = AppName;
Hope it works for you!
I have some code that generates answers based on the user input. But in somecases i need to update the values later by calling SetAnswers But when i compile my code i get the following error:
NullReferenceException: Object reference not set to an instance of an object
I get this error on the line marked by the arrow.
See below for my code:
public class Generate_Questions : MonoBehaviour{
public Question q5, q4;
void Start(){
q4 = create_question("Select object to edit", EXTERNAL);
Visual_Question vq1 = new Visual_Question(1, q4, new vector(1,1,1), Ui, Canvas);
vq1.draw_question();
}
void Update(){
}
public class Visual_Question : Generate_Questions{
public Visual_Question(int order_id, Question q, Vector2 loc, Dictionary<string, RectTransform> ui, RectTransform canvas){
}
public void draw_question(){
q4.SetAnswers(new Answer[]{ <--------- this generates the error.
new Answer(null, "Select an option")
});
}
}
public class Question{
public string text;
public int answers_loc;
public List<Answer> answers;
public Question(string q_text, int answers_loc){
answers = new List<Answer>();
this.text = q_text;
this.answers_loc = answers_loc;
}
public void SetAnswers(Answer[] c_answers){
foreach(Answer answer in c_answers){
this.answers.Add(answer);
}
}
public bool CheckIfAnswersAvailable(){
if(answers.Count > 0){
return true;
}else{
return false;
}
}
public int QuestionLocation(){
return answers_loc;
}
}
public Question create_question(string text, int a_type){
Question Q = new Question(text, a_type);
return Q;
}
public interface IAnswer{
string GetText();
string GetDataType();
object GetValue();
Question GetNextQuestion();
}
public class Answer : IAnswer{
public string text;
public Question next = null;
public int? action = null;
public Element obj = null;
public string property = null;
public float? value = null;
public Answer(Question next, string text){
this.text = text;
this.next = next;
}
public Answer(Question next, string text, Element obj, int? action){
this.action = action;
this.text = text;
this.next = next;
this.obj = obj;
}
public Answer(Question next, string text, Element obj, int? action, string property, float? value){
this.action = action;
this.next = next;
this.text = text;
this.obj = obj;
this.property = property;
this.value = value;
}
public string GetText(){
return text;
}
public string GetDataType(){
throw new System.NotImplementedException();
}
public object GetValue(){
return value;
}
public Question GetNextQuestion(){
return next;
}
}
}
how would i go about fixing this problem? I am a complete newbie to c#. So my question may be already answered but i just dont know what i am looking for.
I assume that IAnswer[] is an interface and since you are trying to initialize an abstract object you get that runtime exception
NullReferenceException: Object reference not set to an instance of an object
if you want to create instance of IAnswer object you have to restructure it like class or structure.
Your class Visual_Question derives from Generate_Questions, so the member q4 that you use en draw_question is not initialized. This is not the member of Generated_Questions but a member of Visual_Question that is not initialized.
In Generate_Questions you are creating a new instance of Visual_Question and then immediately calling draw_question on that new instance. You now have 2 instances of a question (both derive from Generate_Questions), but only one of them has had the Start method, which initializes q4 called. If, however, you attempt to call Start from your second instance, you're going to find yourself in an infinite series of recursive calls and quickly crash with a different error (a stack overflow in this case).
One issue with the current code is that Generate_Questions sounds more like an action than a class. I'd suggest removing the inheritance from Visual_Question and make that an interface that you would implement on Question. Question should probably have the create_question method removed. That probably belongs in a MonoBehavior script (technically it's a factory method -- look up the factory pattern -- I'm not going to go into it here since this is a beginner topic).
Something like (obviously not complete):
public class Generate_Questions : MonoBehaviour
{
private IVisualQuestion q4;
void Start()
{
q4 = new Question("Select object to edit", EXTERNAL);
q4.DrawQuestion(new vector(1,1,1), Ui, Canvas)
}
void Update() {}
}
public interface IVisualQuestion
{
void DrawQuestion(Vector2 loc, Dictionary<string, RectTransform> ui, RectTransform canvas);
}
public class Question : IVisualQuestion
{
// ... insert the Question constructor and code here ...
// Implement VisualQuestion interface
public void DrawQuestion(Vector2 loc, Dictionary<string, RectTransform> ui, RectTransform canvas)
{
this.SetAnswers(new Answer[]{new Answer(null, "Select an option")});
}
}
In general, you probably don't need inheritance. As you learn more C#, you'll discover that when inheritance is going to help it will be clear. More often than not, using an interface is a far better and flexible approach. As a commenter noted, you probably don't want to inherit from MonoBehavior. You really only need that for classes that the Unity Engine is going to directly handle.
Another note: the convention in C# is to name methods, variables, etc. in PascalCase, not using underscores to separate words.
Hi I start learn Fluent NHibernate. I am using this tutorial http://www.d80.co.uk/post/2011/02/20/Linq-to-NHibernate-Tutorial.aspx.
Here is my sample code:
public class Account
{
public virtual int Id { get; set; }
public virtual string Nick { get; set; }
public virtual string Password { get; set; }
}
public class AccountMap:ClassMap<Account>
{
public AccountMap()
{
Id(x => x.Id);
Map(x => x.Nick);
Map(x => x.Password);
}
}
public class NHiberanteHelper
{
private static ISessionFactory _sessionFactory;
private static ISessionFactory SessionFactory
{
get
{
if (_sessionFactory == null)
InitializeSessionFactory();
return _sessionFactory;
}
}
private static void InitializeSessionFactory()
{
_sessionFactory = Fluently.Configure()
//NHibernate bude pouzivat ovladace pre MS SQL 2008
.Database(MsSqlConfiguration.MsSql2008
.ConnectionString(
#"Server=JAN-MSI\SQLEXPRESS;Database=SimpleNHibernate;Trusted_Connection=True;").ShowSql()
)
//urci NHibernatu kde ma hladat mapovacie subory
.Mappings(m=>m.FluentMappings.AddFromAssemblyOf<Account>())
//ak tabs nie su v DB vytvori
.ExposeConfiguration(cfg => new SchemaExport(cfg).Create(true, true))
//vytvori jeden session pre cely life-time apps
.BuildSessionFactory();
}
public static ISession OpenSession()
{
return SessionFactory.OpenSession();
}
}
class Program
{
static void Main(string[] args)
{
using (var session = NHiberanteHelper.OpenSession())
{
using (var trans = session.BeginTransaction())
{
var account = new Account
{
Nick = "dfdwf",
Password = "xxx"
};
session.Save(account);
trans.Commit();
}
}
Console.ReadKey();
}
}
Problem is that this Fluent configuration always drop table in database.
I need only check if table doesnt exist so create table not always when code run drop table.
Your call to new SchemaExport(cfg).Create(true, true) is exporting the configuration to the database. This will drop and re-create it (it's not clever enough to work out the differences and just execute them.
You could use SchemaUpdate, which will update the schema instead. Here's a blog post about it: http://geekswithblogs.net/dotnetnomad/archive/2010/02/22/138094.aspx
I would always prefer to update tables myself or use something like Redgate's SQLCompare to update a schema whilst preserving data.