I am trying to add a boolean column in SubSonic 3.0.0.3 and without this column the code works fine but as soon as I had a bool variable into my model this fails with the following error:
The name "False" is not permitted in this context. Valid expressions are constants, constant expressions, and (in some contexts) variables. Column names are not permitted.
Anyonw know if this should be supported and if it is what I may be doing wrong:
Data Object Class:
public class Desk
{
[SubSonicPrimaryKey]
public int DeskId { get; set; }
public string DeskName { get; set; }
public string SAPCode { get; set; }
public int LocationId { get; set; }
public bool Active { get; set; }
}
Use of Class:
var d = new Desk();
d.DeskName = "Test";
d.SAPCode = "12345";
d.LocationId = 2;
d.Active = true;
var repository = new SimpleRepository("SubSonicTesting", SimpleRepositoryOptions.RunMigrations);
repository.Add(d);
I have faced the exact same issue (version 3.0.0.3) when I added a bool property named "IsAccountOwner". The problem seems to be with migrations because when I deleted the table, SubSonic re-created it correctly with the added column.
I'm using SQL Server 2008 Express, in case that matters. The error is related to a malformed query perhaps?
Related
I'm trying to do a simple Join on 2 tables and return a Value Tuple of those two tables.
public partial class DeliveryMethod
{
[Required]
[PrimaryKey]
public int DeliveryMethodId { get; set; }
[References(typeof(Event))]
[Required]
public string EventId { get; set; }
[References(typeof(DeliveryType))]
[Required]
public short DeliveryTypeId { get; set; }
[Required]
public int MappedValue { get; set; }
}
public partial class DeliveryType
{
[Required]
[PrimaryKey]
public short DeliveryTypeId { get; set; }
[Required]
public string DeliveryTypeDescription { get; set; }
}
public List<(DeliveryMethod deliveryMethod, DeliveryType deliveryType)> GetDeliveries(string eventId)
{
using (var db = DbFactory.OpenDbConnection(...))
{
var q = db.From<DeliveryMethod>()
.Join<DeliveryType>((dm, dt) => dm.DeliveryType == dt.DeliveryType)
.Where(dm => dm.EventId == eventId)
.Select<DeliveryMethod, DeliveryType>((dm, dt) =>
new {dm, dt});
return db.Select<(DeliveryMethod deliveryMethod, DeliveryType deliveryType)>(q);
}
}
However, when I run this, I get a NullReferenceException. This seems to be because ConvertToValueTuple in OrmLiteUtils only has converters for basic types like string, int, DateTime, etc. and GetConverter(fieldType) returns null when it's a type of a custom object.
Is there a work around this? Or some way to return a value tuple of more complex, custom objects instead of just basic tuples like (int id, string name, DateTime time)?
P.S. I tried to simplify my problem by simplifying the classes so if I made a mistake there, I apologize for that but I think you can get the basic idea behind my question.
You can only use OrmLite's C# 7 Tuple support by selecting columns, not entire tables, e.g:
.Select<DeliveryMethod, DeliveryType>((dm, dt) =>
new {dm.EventId, dt.DeliveryMethodId});
var results = db.Select<(string, int)>(q);
For Selecting entire tables checkout OrmLite's SelectMulti API, e.g:
var q = db.From<DeliveryMethod>()
.Join<DeliveryType>((dm, dt) => dm.DeliveryType == dt.DeliveryType)
.Where(dm => dm.EventId == eventId);
var results = db.SelectMulti<DeliveryMethod, DeliveryType>();
I have a ServiceStack service using autoquery where the DateTime greater than or less than are being ignored.
Here is my request DTO:
public class GetSources : QueryBase<DbSource, Source>
{
public string Name { get; set; }
public string NameContains { get; set; }
public string NameStartsWith { get; set; }
public DateTime? LastUpdatedDateGreaterThan { get; set; }
public DateTime? LastUpdatedDateLessThan { get; set; }
}
The database table poco generated from the ormlite T4 template looks like this:
[Alias("DbSources")]
[Schema("SomeSchema")]
public partial class DbSource
{
[AutoIncrement]
public int Id { get; set;}
[Required]
public string Name { get; set;}
[Required]
public DateTime LastUpdatedDate { get; set;}
}
In the service I do some validation and then use AutoQuery like this:
var q = AutoQuery.CreateQuery(dto, Request.GetRequestParams());
q.Join<DbSource, CompanySource>((source, companySource) => source.Id == companySource.SourceId && companySource.CompanyID == companyId);
return AutoQuery.Execute(dto, q);
I'm using mstest
[TestMethod]
public void GetSources_LastUpdatedGreaterThan()
{
var expected = DateTime.Now;
var query = new GetSources { LastUpdatedDateGreaterThan = expected};
QueryResponse<Source> result;
using (var service = appHost.Container.Resolve<SourceService>())
{
service.Request = new MockHttpRequest();
result = service.Any(query);
}
log.Info(result.ToJson());
result.Results.ForEach(src => Assert.IsTrue(src.LastUpdatedDate > expected));
}
Name, NameContains, and NameStartsWith all work as expected in other tests, but both LastUpdatedDateGreaterThan and LastUpdatedDateLessThan do not generate a where clause. In my AutoQuery setup all of the properties are defaults except for EnableUntypedQueries which is false.
I know I can explicitly add the where for them in the service. i.e.
q.Where(source => source.LastUpdatedDate > dto.LastUpdatedDateGreaterThan);
But if possible I would like AutoQuery to take care of it. Does DateTime work with AutoQuery? Or am I doing something wrong in my code.
I ran through the Servicestack AutoQuery unit tests that mythz created using sql server. I tested using a database view which my original project was querying against and I wasn't able to replicate the issue I'm having. For now I'm going to just add the QueryField attribute to the DateTime properties on the Query model like this:
[QueryField(Template = "{Field} > {Value}", Field = "LastUpdatedDate")]
public DateTime? LastUpdatedDateGreaterThan { get; set; }
Adding the attribute gives me what I need. I'll spend some time tracking down the culprit in my code later.
I am using these classes:
public class MasteryPages
{
internal MasteryPages() { }
[JsonProperty("pages")]
public List<MasteryPage> Pages { get; set; }
[JsonProperty("summonerId")]
public long SummonerId { get; set; }
}
[Serializable]
public class MasteryPage
{
internal MasteryPage() { }
[JsonProperty("current")]
public bool Current { get; set; }
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("talents")]
public List<Talent> Talents { get; set; }
}
[Serializable]
public class Talent
{
internal Talent() { }
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("rank")]
public int Rank { get; set; }
}
This is the code I'm using to deserialise the object
//MASTERIES
var jsonMasteries = requester.CreateRequest(string.Format(RootUrl, Region) + string.Format(MasteriesUrl, summonerId));
var objAllMasteryPages = JsonConvert.DeserializeObject<MasteryPages>(jsonMasteries);
The jsonMasteries object is correctly serialized and gives me this:
http://pastebin.com/3dkdDHdx (Rather large, to view easily: go to http://www.jsoneditoronline.org/ and paste it)
The second line is giving me troubles however. Normally my object should be filled with the data. It unfortunately isn't and I have no idea what's wrong.
Anyone could help me out?
Your problem is in this part of serialized JSON: "42177333": { ... }
As I understand - this is some kind of ID and it's dynamic.
Possible solutions are:
One of possible resolutions is here: C# deserialize dynamic JSON
Cut this part of dynamic JSON.
Try to modify the serialization stuff to avoid this dynamic ID.
Thanks to sleepwalker I saw what was wrong. (Dynamic Id (number), first line)
Now, the James Newtonking JSON library has a solution for dynamic id's like this.
I edited my code to this:
var jsonMasteries = requester.CreateRequest(string.Format(RootUrl, Region) + string.Format(MasteriesUrl, summonerId));
var objAllMasteriePages = JsonConvert.DeserializeObject<Dictionary<long, MasteryPages>>(jsonMasteries).Values.FirstOrDefault().Pages;
(First line stays the same, the magic is in the second line)
Now, i use a dictionary with the key being my given Id, and my custom class.
This works wonders
I am getting an Object reference not set to an instance of an object error when trying to add multiple entity levels to my EF context.
Take the following three-level example class structure:
public class Forum
{
public int ID { get; set; }
public string Name { get; set; }
public virtual ICollection<Blog> Blogs { get; set; }
}
public class Blog
{
public int ID { get; set; }
public string Name { get; set; }
public int ForumID { get; set; }
public virtual Forum Forum { get; set; }
public virtual ICollection<Post> Posts { get; set; }
}
public class Post
{
public int ID { get; set; }
public string Name { get; set; }
public int BlogID { get; set; }
public virtual Blog Blog { get; set; }
}
For a given Forum, I want to add a new Blog with a new Post:
Forum MyForum = context.Forums.Find(1);
Blog MyBlog = new Blog { Name = "My New Blog" };
Post MyPost = new Post { Name = "My New Post" };
MyForum.Blogs.Add(MyBlog); // This WORKS
MyBlog.Posts.Add(MyPost); // This FAILS
context.SaveChanges(); // We never make it this far
I've tried every possible order combination, including placing context.SaveChanges() immediately after .Add(MyBlog). It seems like it's choking because there is no Blog.ID to use for Post.BlogID, but EF generates temporary key values for use in this situation.
Any ideas?
Hints at the answer (and the root problem) can be found at:
Entity Framework Uninitialised Collection
Entity Framework 4.1 Code First - Should many relationship ICollections be initialised
The "simple" solution is to manually initialize the Blog.Posts collection:
Blog MyBlog = new Blog { Name = "My New Post", Posts = new List<Post>() };
Alternatively, you can build this logic into the class constructor as recommended by Ladislav in the second link.
Basically, when you create a new object, the collection is null and not initialized as a List<>, so the .Add() call fails. The Forum.Blogs collection is able to lazy-load because it derives from the database context. Blog.Posts, however, is created from scratch, and EF can't help you, so the collection is null by default.
My project is the throwing the above error because the Ship Date in my table is null. I am using Code First, and the DateTime field is declared as nullable both in the generic set and the SQL table. I am populating a gridview with the result set. Ideally, I would like to have the gridview display "not yet shipped" when the ShipDate field is null, but at this point, I would be happy just to be able to display the record. Any help is greatly appreciated. Here is the code-behind and the context class that I am using:
public class Order
{
[Key]
public int OrderID { get; set; }
public int CustomerID { get; set; }
public string ShipAddress { get; set; }
public string ShipCity { get; set; }
public string ShipState { get; set; }
public string ShipZip { get; set; }
[ScaffoldColumn(false)]
public string PaymentTransactionID { get; set; }
[ScaffoldColumn(false)]
public System.DateTime OrderDate { get; set; }
public System.DateTime? ShipDate { get; set; }
public virtual Customers Customers { get; set; }
public List<OrderDetail> OrderDetails { get; set; }
}
The code behind is:
public List<OrderDetail> FetchByOrderID()
{
int myOrderID = CusOrderId;
ProductContext db = new ProductContext();
return db.OrderDetails.Where(
c => c.OrderID == myOrderID).ToList();
}
I was getting the above error when trying to get the max(date_column) through LINQ. The column was defined as NOT NULL and when there are no rows returned in the query its trying to assign null to the DateTime property that's representing the date column. One solution is to change the date column to being NULLable which will create the entities property as type DateTime?
I use VB.Net, but had a similar problem. I do not know if you fixed your problem.
But I declared the variable as Nullable(Of Date) and that did the trick to me. I am told that adding the "?" does the similar thing, but unfortunately did not work out for me, or I did not do it correctly. :o)
private DateTime? _settlementDate {get;set;}
I was having a similar problem, same error.
Turns out I failed to setup my ConnectionString in the configuration.