LINQ to SQL - Multiple Anonymous Columns - sql

I am trying to update my DBML file for a stored procedure and it is returning an error that I have never seen before and tried to find a reputable resource for solving and have been unable to at this point. The error is:
Unsupported Stored Procedure Unable to extract stored procedure
'procedurename' because its result set contains multiple anonymous
columns.
I have loaded this stored procedure into the DBML successfully numerous times. What might be causing the issue all of the sudden? Thanks!
Here is what the auto-generated data-class code used to look like (restored from a backup). I hope it helps decipher what is going on.
[global::System.Data.Linq.Mapping.FunctionAttribute(Name="dbo.parseXMLForK12_EachStudent")]
public ISingleResult<parseXMLForK12_EachStudentResult> parseXMLForK12_EachStudent([global::System.Data.Linq.Mapping.ParameterAttribute(DbType="NVarChar(MAX)")] string strXML, [global::System.Data.Linq.Mapping.ParameterAttribute(DbType="Date")] System.Nullable<System.DateTime> datesaved, [global::System.Data.Linq.Mapping.ParameterAttribute(DbType="Int")] System.Nullable<int> filepassed, [global::System.Data.Linq.Mapping.ParameterAttribute(DbType="Int")] System.Nullable<int> whichproc)
{
IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), strXML, datesaved, filepassed, whichproc);
return ((ISingleResult<parseXMLForK12_EachStudentResult>)(result.ReturnValue));
}
public partial class parseXMLForK12_EachStudentResult
{
private System.Nullable<int> _Column1;
public parseXMLForK12_EachStudentResult()
{
}
[global::System.Data.Linq.Mapping.ColumnAttribute(Name="", Storage="_Column1", DbType="Int")]
public System.Nullable<int> Column1
{
get
{
return this._Column1;
}
set
{
if ((this._Column1 != value))
{
this._Column1 = value;
}
}
}
}

Related

How to preserve variable value between application starts in ASP.Net Core MVC?

I have an ASP.NET Core MVC application that might be restarted from time to time (maintenance); how can make some variable values persistent from an execution to the next?
PS: That's the code that needs to write value as persistent. For example "LastMaintenanceRestartTime = 03/04-2020", the maintenance restart occurs once a day so the code needs to remember the last time it was restarted.
In UWP, I could do the following code but I can't seem to find an equivalent for ASP.NET Core:
Windows.Storage.ApplicationData.Current.LocalSettings.Values[key] = value;
The best I could find is the following code but the values are only persistent within the same execution:
AppDomain.CurrentDomain.SetData(key, value);
Some talk about "Application.Settings" but I can't seem to be able to reach this namespace...
I've also seen some people talking about "AppSettings" files that can be modified during execution but it seems rather complex to keep a simple value persistent...
Do you have any recommendation, solution or ideas for me?
I found the solution:
static void ReadSetting(string key)
{
try
{
var appSettings = ConfigurationManager.AppSettings;
string result = appSettings[key] ?? "Not Found";
Console.WriteLine(result);
}
catch (ConfigurationErrorsException)
{
Console.WriteLine("Error reading app settings");
}
}
static void AddUpdateAppSettings(string key, string value)
{
try
{
var configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
var settings = configFile.AppSettings.Settings;
if (settings[key] == null)
{
settings.Add(key, value);
}
else
{
settings[key].Value = value;
}
configFile.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection(configFile.AppSettings.SectionInformation.Name);
}
catch (ConfigurationErrorsException)
{
Console.WriteLine("Error writing app settings");
}
}
Link: https://learn.microsoft.com/en-us/dotnet/api/system.configuration.configurationmanager.appsettings?redirectedfrom=MSDN&view=dotnet-plat-ext-5.0#System_Configuration_ConfigurationManager_AppSettings
Create a model to save data and last execution time
public class ApplicationData {
public DateTime LastExecutionTime {get;set;}
public string Data {get;set;}
public bool isRunningFirstTime {get;set}
}
1.On first application run, model should be updated to current values and isRunningFirstTime should be set to false.
2. On second run, read or update values based on date and application running count
Expanding on #rashidali answer (and not saying best, but):
public class ApplicationData
{
private DateTime _lastExecutionTime;
public DateTime LastExecutionTime
{
get
{
_lastExecutionTime = (read from file/database);
return _lastExecutionTime;
}
set
{
_lastExecutionTime = value;
(write _lastExecutionTime to file/database);
}
}
public string Data {get;set;}
public bool isRunningFirstTime {get;set}
}

ASP.NET Core : get stored procedure results to a view model

I have a view model called TdetailsVM as below:
public class TdetailsVM
{
public Tournaments tourney { get; set; }
public List<Participants> currentlyjoined { get; set; }
}
Now in the controller I am passing an ID of the tournament to the task:
public async Task<IactionResult> Details(guid id)
{
var ThisTourney = _context.Tournaments.FirstOrDefaultAsync(m => m.TID == id);
This will return the value for a specific tournament into ThisTourney where I pass it later to the view model
I need something similar like:
var ThisParticipants = (result "has many rows" from a stored procedure called SP_GetParticipants that needs a parameter =id)
Then I can pass the values to the view model as below
TdetailsVM tvm = new TdetailsVM()
{
tourney = ThisTourney,
currentlyjoined = ThisParticipants
}
// then I can return the view
return view(tvm);
Passing the data for the first requirement is fine and it works but how can I pass the stored procedure ?
Many thanks in advance
If you are using Entity Framework Core, then for calling your stored procedure you can use this line of code.
List<Participants> participants= _context.Participants.FromSql("SP_GetParticipants #ID",id).ToList();
Note how I passed #ID value to the stored procedure in FromSql
method and how mapped the result to List<Participants>. Please have a look at raw sql for more information.
After this line of code you have you list of Participants, then you can fill your parent ViewModel.
var result = new TdetailsVM
{
Tourney = thisTourney,
Currentlyjoined = Participants
};
Note that it is recommended to use PascalCase for naming your public
properties in your class (ViewModel) and camelCase for your
private ones. Please take a look at General Naming Conventions
for more information.

Entity Framework SQL query throwing a conversion error

I have this simple query where I want to return a column of a record from a table which can be either 1 or 0. I am trying to use this query but I get a conversion error:
System.InvalidCastException: 'Unable to cast object of type 'System.Boolean' to type 'System.Int32'.'
public int GetUserValidFlag(int userId)
{
var query = from r in db.VisUsers
where r.UserId == userId
select r.IsValid;
return Convert.ToInt32(query.FirstOrDefault());
}
I do have an instance of db in this class.
Context:
public class DatabaseContext : DbContext
{
public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options)
{
}
public DbSet<Category> Categories { get; set; }
public DbSet<SubCategory> SubCategories { get; set; }
public DbSet<VisUser> VisUsers { get; set; }
public DbSet<Project> Projects { get; set; }
}
I have also tried with Find():
public int GetUserValidFlag(int userId)
{
var record = db.VisUsers.Find(userId);
return Convert.ToInt32(record.IsValid);
}
NOTE: these two attempts do not reach the return statements, the error occurs before the return.
I am unsure where/why this conversion error is occurring, I can make it work with stored procedure but I would like to understand why this version is failing.
Databases generally store Boolean flags as Bit fields with values of 1 or 0. EF will map these to entities as Boolean type. Typically in your code you would just use bool as the data type for methods and properties for a flag like this. If you do still want to convert it to an Int then you also need to consider whether the DB value was null-able or not:
If the DB value is not null-able:
return query.Single() ? 1 : 0;
FirstOrDefault should only be used with an order-by clause in cases where you expect 0 or many possible results. If you are expecting 1 user with that Id, use Single. This will throw an exception if the User ID doesn't match a record, or if more than 1 record was returned. Using the OrDefault varieties will gunk things up if a User record was not found. If you want to explicitly check and handle the possibility that no record exists, then use an OrDefault method, otherwise it's better to handle it as an exception.
If the DB value for the query is null-able:
bool? isValid = query.Single();
return isValid.HasValue && isValid.Value ? 1 : 0;
This checks the value and returns 1 if the value is present and True, otherwise it returns 0.

NHibernate vs petapoco loading mechanism

I am having the difficulty to understand NHibernate an petapoco loading mechanism. Actually I did a test to compare how both behave upon a query.
My class is as follows:
UserTest.cs with the following properties:
private string name;
private int id;
private int customerId;
public int ID
{
get { return id; }
set { id = value; }
}
public string Name
{
get { return name; }
set { name = value; }
}
public int? CustomerID
{
get { return customerId; }
set
{
if (value != customerId)
{
customerId = value;
if (this.ID > 0)
{
DoSomeOtherWork();
}
}
}
}
When I do a User.Load in NHibernate, I have observed that DoSomeOtherWork is never called whereas in PetaPoco, when I do a query from loading User such as Connection.db.Fetch<UserTest>(...) or Connection.db.Query<UserTest>(...), I can see that DoSomeOtherWork is called.
Why is that so?
Is there a way to avoid calling DoSomeOherWork when using PetaPoco such that it has the same behaviour as NHibernate? I dont want to usePetaPoco.Ignoreas I need to get and set theCustomerID`.
PetaPoco it a micro-ORM (much lighter than Nhibernate) and materializes your POCO object when you fetch the record. There is no other magic than that, so the answer is:
No, you can't avoid calling the setter of the property.

Automatic Schema Validation using NHibernate/ActiveRecord

Let's assume I have a table of Products with columns: Id, Name, Price
and using NHibernate (or ActiveRecord) I map the table to the POCO:
public class Product
{
public virtual long Id { get; set; }
public virtual string Name { get; set; }
public virtual double Price { get; set; }
}
Now if someday a new column named ShipmentPrice (let's assume it's double too)
will be added to the Products table, is there any way I can automatically know that?
For saying automatically I mean adding code to do that or getting an exception?
(I assume I don't have control on the columns of the table or a way to
know of any changes to the table's schema in advance)
You do recall correctly, Mauricio. The following code shows how you can create or update a schema. The update will run when Validate() raises an exception. No exception will be thrown when a field is available in the database but not in the configuration. It is perfectly legal to have extra fields: you don't want them to be deleted, I hope? That could cause tremendous damage...
The following code shows Test, Create, Validate and Update, each step with the proper exception handling. The code is simplified, but it should give you a handle on how to do a validation.
This code helps with Entity-centric (POCO) ORM configurations, where you can add a field to your class and it will automatically be updated in the database. Not with table-centric, where fields are leading.
// executes schema script against database
private static void CreateOrUpdateSchema(Configuration config)
{
// replace this with your test for existence of schema
// (i.e., with SQLite, you can just test for the DB file)
if (!File.Exists(DB_FILE_NAME))
{
try
{
SchemaExport export = new SchemaExport(config);
export.Create(false, true);
}
catch (HibernateException e)
{
// create was not successful
// you problably want to break out your application here
MessageBox.Show(
String.Format("Problem while creating database: {0}", e),
"Problem");
}
}
else
{
// already something: validate
SchemaValidator validator = new SchemaValidator(config);
try
{
validator.Validate();
}
catch (HibernateException)
{
// not valid, try to update
try
{
SchemaUpdate update = new SchemaUpdate(config);
update.Execute(false, true);
}
catch (HibernateException e)
{
// update was not successful
// you problably want to break out your application here
MessageBox.Show(
String.Format("Problem while updating database: {0}", e),
"Problem");
}
}
}
}
-- Abel --
You could use NHibernate's SchemaValidator, but IIRC it only checks that your mapped entities are valid so it doesn't check if there are more columns than mapped properties since that wouldn't really break your app.