ActiveAndroid NPE from execute - sqlite

I am following https://github.com/pardom/ActiveAndroid/wiki/Querying-the-database to incorporate activeandroid in my application like so:
#Table(name="Contact")
public class Contact extends Model implements Serializable, Comparable {
public Contact() {
super();
}
public Contact(String id, String n, String c, String p, String addr, String phone,
String fb, String twit, String yt) {
super();
candID = id;
name = n;
chamber = c;
party = p;
address = addr;
phoneNo = phone;
facebook = fb;
twitter = twit;
youtube = yt;
}
public static List<Contact> getCachedContactsByState(String stateAbbr) {
/*return new Select().from(Contact.class).where("state = ?",
stateAbbr).execute();*/
Select s = new Select();
From f = s.from(Contact.class);
f = f.where("state = ?", stateAbbr);
List<Contact> cachedContacts = f.execute();
return cachedContacts;
}
According to my debugger, the f.execute throws a null pointer exception, and f is not null.
just making sure, the tutorial didn't mention needing to install sqlite before using activeandroid, and it said the point of activeandroid was to use objects and their functions to do CRUD on sqlite, so I'm assuming I just needed to follow the tutorial to create and query my sqlite db?

Looks like you've forgotten to call ActiveAndroid.initialize() with a valid Context. See the Getting Started section from the documentation you linked to.

Related

How to add data to associative table in asp.net core

I am new to asp.net core. I am building a web application for book management. I have a table called Author and books. Being a many to many relationships I made an associative entity that consists of the bookId and authorId. When I try to create I am able to create author and book. I successfully added the author and book to the database.
My author class looks like this
public class Author
{
private int _ID
private string _Name;
public string ID {
get { return _ID; }
set { _ID = value; }
public string Name {
get { return _Name; }
set { _Name = value; }
}
My book class is
public class Author
{
private int _ID
private string _Name;
private string _Title;
public string ID {
get { return _ID; }
set { _ID = value; }
}
public string Title {
get { return _Name; }
set { _Name = value; }
}
public string Name {
get { return _Name; }
set { _Name = value; }
}
I have a data access called db.cs to help to create the book and author in database.
public static int AddAuthor(Author A)
{
int renum = -1;
SqlConnection conn = null;
conn = new SqlConnection(ConnectionString);
conn.Open();
SqlCommand comm = new SqlCommand("sproc_AuthorAdd", conn);
comm.CommandType = System.Data.CommandType.StoredProcedure;
comm.Parameters.AddWithValue("#Name", A.Name);
comm.Parameters.AddWithValue("#Title", a.Title);
SqlParameter output = new SqlParameter();
output.ParameterName = "#AuthorID";
output.DbType = System.Data.DbType.Int32;
output.Direction = System.Data.ParameterDirection.Output;
comm.Parameters.Add(output);
int affect = comm.ExecuteNonQuery();
renum = affect;
c.ID = (int)output.Value;
I have done the same for books as well. I want to fill out the association table as well when the user filled out a book and author using their ID. I tried to do various things like using a cookie to pass data. But I cannot store data. Any kind of help is appreciated. Thanks in advance.
I'm not really sure I understand your last code snippet, but if you're having issues managing your many-to-many relationship between Books and Authors, have you considered just using Entity Framework Core?
Instead of writing a bunch of code that accesses your database, you just create models of your tables (similar to the classes you have defined above), and it handles the many-to-many relationship for you. The code to query for Authors and/or Books could then look as simple as:
using (var db = new dbContext())
{
var books = db.Books
.Where(b => b.ID > 1234)
.OrderBy(b => b.Title)
.ToList();
}
And creating a new Book or Author would be similarly simple:
using (var db = new dbContext())
{
var book = new Book { ID = 1234, Title = "Some Title", Name = "Some Name" };
db.Books.Add(book);
db.SaveChanges();
}
You might have to reimplement a bunch of things to take advantage of Entity Framework Core in your app, but it sounds like it would save you time in the long run.

How to dynamically use getters/setters in Dart

class User{
String firstName;
String lastName;
String email;
}
I want to be able to get and set one of the fields in user with a dynamically selected symbol or string. For example String value = u[new Symbol("firstName")];
I see that InstanceMirror has a getField method, but it doesn't seem to return the value. All I need is the value.
If you create a symbol with # you need to know the name at compile time.
I got it working this way:
library operator_lib;
import 'dart:mirrors';
void main(List<String> args) {
var x = new X();
var f = new Symbol('firstName');
var r = reflect(x);
print(r.getField(f).reflectee);
r.setField(f, "John");
print(r.getField(f).reflectee);
}
class X {
String firstName = 'Mike';
}

Load ProfileBase without HTTP Context

I'm in the process of converting user profile data that was serialized in the classic ASP.Net Membership Provider for use in SimpleMembership. I cannot figure out how to get the ProfileBase object for every user in the system.
If a specific user is logged in, I can do something like:
MyModel myModel =
(MyModel)HttpContext.Current.Profile.GetPropertyValue("MyKey");
where MyKey refers to a profile key established in web.config like this:
<add name="MyModel" type="MyNS.MyModel" serializeAs="Binary" />
However, without the benefit of an HTTP context (I'm trying to do this for all users in the system, not a logged-in user) I can't figure out how to load the profile and ultimately an instance of MyModel for each user in the system.
I have tried:
ProfileInfoCollection profiles =
ProfileManager.GetAllProfiles(ProfileAuthenticationOption.All);
foreach (var profile in profiles)
{
var pi = (ProfileBase)profile;
// OOPS! Unfortunately GetAllProfiles returns
// ProfileInfo and not ProfileCommon or ProfileBase
}
and
MembershipUserCollection existingUsers = Membership.GetAllUsers();
foreach (MembershipUser mu in existingUsers)
{
mu. // OOPS! No link to the profile from the user...
}
How can I retrieve the ProfileCommon or ProfileBase instance for each profile in the system, and thus ultimately the MyModel associated with each user?
Since I could not find an answer to this question, I opted to just read the profile data directly from SQL.
It turns out that the format is straightforward. In aspnet_Profile:
PropertyNames uses a format NameOfProperty:TypeFlag:Offset:Length (repeat for all properties).
FlagType is "S" for string or "B" for binary
Offset is the offset in the appropriate data field
Length is the length of data in the appropriate data field
PropertyValuesString holds all string properties concatenated without a delimiter.
PropertyValuesBinary holds all binary properties concatenated without a delimiter.
BinaryFormatter is used to serialize binary (non-string) properties
Here's a little code I wrote to parse the data:
private class Migrate_PropNames
{
public string Name { get; set; }
public bool IsString { get; set; }
public int Offset { get; set; }
public int Length { get; set; }
}
....
Dictionary<string, Migrate_PropNames> propInfo = ParsePropInfo(propertyNames);
// Example string property
string firstName = Migrate_GetString(propInfo["FirstName"], propertyValuesString);
// Example binary property
MyType myType =
Migrate_GetBinary<MyType>(propInfo["MyTypeKey"], propertyValuesBinary));
private T Migrate_GetBinary<T>(Migrate_PropNames propNames, byte[] propertyValuesBinary)
{
byte[] data = new byte[propNames.Length];
Array.Copy(propertyValuesBinary, propNames.Offset, data, 0, propNames.Length);
var fmt = new BinaryFormatter();
using (var ms = new MemoryStream(data))
{
T original = (T)fmt.Deserialize(ms);
return original;
}
}
private string Migrate_GetString(Migrate_PropNames propNames, string propertyNames)
{
return propertyNames.Substring(propNames.Offset, propNames.Length);
}
private Dictionary<string, Migrate_PropNames> ParsePropInfo(string propertyNames)
{
Dictionary<string, Migrate_PropNames> result = new Dictionary<string,Migrate_PropNames>();
string[] parts = propertyNames.Split(new string[] { ":"}, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < parts.Length; i += 4)
{
Migrate_PropNames pn = new Migrate_PropNames();
pn.Name = parts[i];
pn.IsString = (parts[i + 1] == "S");
pn.Offset = int.Parse(parts[i + 2]);
pn.Length = int.Parse(parts[i + 3]);
result.Add(pn.Name, pn);
}
return result;
}
I hope this helps someone. I'll gladly accept a different answer that correctly shows how to use the API.
From the ProfileInfo or MemberShipUser object, you should can get a ProfileBase one using ProfileBase.Create(string username).

C# Error: Cannot read from a Closed reader...?

I have this code below. Gets data and sets data property to the values gathered.
public struct TrblShootData
{
public List<string> Logins;
public IEnumerable<Hieracrhy> Hierarchy;
public IEnumerable<EmployeeTeam> EmpTeam;
}
public TrblShootData TroubleShootData
{
get;
private set;
}
class DataGetter
{
public void GetData(string FirstName, string LastName, string Login, string Email, bool isFirstName, bool isLastName, bool isLogin, bool isEmail)
{
List<string> logins = null;
IEnumerable<Hieracrhy> hier = null;
IEnumerable<EmployeeTeam> tmemp = null;
TrblShootData tsData = new TrblShootData();
queries q = BuildQuery(FirstName, LastName, Login, Email, isFirstName, isLastName, isLogin, isEmail);
if (q.isValidQueries)
{
DataContext1 mscDB = new DataContext1 ();
using (DataContext2 opsDB = new DataContext2 ())
{
tmemp = opsDB.ExecuteQuery<EmployeeTeam>(q.qryEmployeeTeam);
}
using (DataContext3 rptDB = new DataContext3 ())
{
hier = rptDB.ExecuteQuery<Hieracrhy>(q.qryHierarchy);
if (hier != null)
{
logins = hier.Select(s => s.SalesRepLogin).Distinct().ToList();
}
}
tsData.EmpTeam = tmemp.Select(r=>r);
tsData.Hierarchy = hier.Select(r => r);
tsData.Logins = logins.Select(r => r).ToList();
TroubleShootData = tsData;
}//if
}
}
From another class I attempt to do this:
tshtr.GetData(txtFirstName.Text, txtLastName.Text, txtLogin.Text, txtEmail.Text, chkFirstName.Checked, chkLastName.Checked, chkLogin.Checked, chkEmail.Checked);
gvEmpTeams.DataSource = tshtr.TroubleShootData.EmpTeam;
gvHierarchy.DataSource = tshtr.TroubleShootData.Hierarchy;
gvEmpTeams.DataBind();
gvHierarchy.DataBind();
But at the DataBind() I get an error saying that I cannot read from a closed reader.
I'm not seeing why it would throw this error when I've set my property as above after I've assigned the values in the usings. So I'm not seeing how this is trying to use a closed reader.
Thanks for any help!
Because of deferred execution, your query only executes when the data-binding engine enumerates its results, after you close the DataContext.
You need to call .ToList() before closing the DataContext to force it to be evaluated immediately.

nice overload structure

I have created a library function and want to add an overload that does a very similar thing with an additional parameter. The existing code looks like this:
public class MealsAllocation
{
public int mealId;
public List<CrewSummary> crew;
private MealsAllocation() { }
public MealsAllocation(int MealId) {
mealId = MealId;
string connStr = ConfigurationManager.ConnectionStrings["LocalSqlServer"].ConnectionString;
SqlConnection conn = new SqlConnection(connStr);
//first fill an ienumerable redemption object for the meal
List<MealRedemption> mealRedemptions = new List<MealRedemption>();
SqlCommand cmdRed = new SqlCommand("tegsGetMealsRedemption", conn);
cmdRed.CommandType = CommandType.StoredProcedure;
cmdRed.Parameters.Add(new SqlParameter("#mealId", MealId));
conn.Open();
SqlDataReader drRed = cmdRed.ExecuteReader();
while (drRed.Read())
{
MealRedemption mr = new MealRedemption(Convert.ToInt32(drRed["crewId"]), Convert.ToDateTime(drRed["creation"]), Convert.ToInt32(drRed["redeemed"]));
mealRedemptions.Add(mr);
}
conn.Close();
//then fill the crew list
crew = new List<CrewSummary>();
SqlCommand cmdCrew = new SqlCommand("tegsGetMealsAllocation", conn);
cmdCrew.CommandType = CommandType.StoredProcedure;
cmdCrew.Parameters.Add(new SqlParameter("#mealId", MealId));
conn.Open();
SqlDataReader drCrew = cmdCrew.ExecuteReader();
while (drCrew.Read())
{
int drCid = Convert.ToInt32(drCrew["id"]);
List<MealRedemption> drMr = mealRedemptions.FindAll(red => red.crewId == drCid) ;
CrewSummary cs = new CrewSummary(drCid, Convert.ToInt32(drCrew["allocation"]), drMr );
crew.Add(cs);
}
conn.Close();
}
So then now I wish to add a new overload that will look a bit like this:
public MealsAllocation(int MealId, int crewId)
{
}
and essentially this will do much the same but slightly different from the above.
What would be a good strategy to avoid "copy and paste inheritance" ?
ie a nice way to refactor the above so that it lends itself more easily to the overload?
How about moving your logic to an internal function so it's only accessible in this assembly, and to this class and use optional parameters... something like this:
public class MealsAllocation
{
public int mealId;
public List<CrewSummary> crew;
private MealsAllocation()
{
}
public MealsAllocation(int MealId)
{
DoWork(MealId);
}
public MealsAllocation(int MealId, int crewId)
{
DoWork(MealId, crewId);
}
internal void DoWork(int MealId, int crewId = -1)
{
// have your logic here based on your parameter list
// valid crewId passed, then add new param for DB proc
if (crewId > -1)
{
cmdCrew.Parameters.Add(new SqlParameter("#crewId", crewId));
}
}
}
You can user object initializer
var mealRedemption = new
{
MealId = yourvlue,
Crew = crew
};
Link : http://msdn.microsoft.com/en-us/library/bb384062.aspx
Since you want to overload your constructor, you could also try such an approach:
public MealsAllocation(int MealId) : this (MealId, null)
{
}
public MealsAllocation(int MealId, int? crewId)
{
// Initialize your instance as needed
if (crewId.HasValue)
{
// Do some more stuff
}
}
Although I don't recommend doing all that inside the constructor, you can simply add an optional param to the end:
public class MealsAllocation
{
public int MealId { get; set; }
public int CrewId { get; set; }
public List<CrewSummary> Crew { get; set; };
public MealsAllocation(int mealId, int crewId = 0)
{
this.MealId = mealId;
this.CrewId = crewId;
if(this.CrewId = 0) // etc...
}
Side note: You need to add the using statement around your SqlConnection, SqlCommand and SqlDataReader object or you could run into connection and/or memory leaks. Personally, I'd create a Data Access layer and put all of the data related methods there to make them reusable across your entire business layer.
Also, I think this might be a good candidate for the Lazy<T> object: http://msdn.microsoft.com/en-us/library/dd642331.aspx
The first thing that comes to mind is to split that big chunk of code in two different methods
giving at each method a specialized functionality
public MealsAllocation(int MealId)
{
List<MealRedemption> mealRedemptions = LoadMealRedemptions(MealID);
LoadCrewSummaryByMeal(mealRedemptions, MealID);
}
while the other constructor could be
public MealsAllocation(int MealId, int crewId)
{
List<MealRedemption> mealRedemptions = LoadMealRedemptions(MealID);
LoadCrewSummaryByCrew(mealRedemptions, MealID, crewID);
}
In the first constructor you call the private method where you load the MealRedemptions list, get its output and pass to a specialized method that load the CrewSummary list using only the MealID and the list obtained from the first method.
In the second constructor you could use the same method used in the first one and then use a different one for the loading of the CrewSummary. The requirements of your second constructor are not clear and could change the design of this second method (I mean, how do you use the crewID parameter to change the inner workings to build the CrewSummary list?)

Resources