OData-query is throwing error for $expand query - asp.net-web-api

There are two tables "Task" and "Client". Both this tables are related with ClientId (foreign key).
In this query I'm trying to get the client name based on ClientId from Task table with $expand keyword. Below is the query and Entity classes.
OData Query : http://localhost:52484/Task?$expand=Client($select=Name)
public class Task: GeneralTask
{
public Task() { }
public Task(
int clientId,
string title,
)
{
this.Title = title;
this.ClientId = clientId;
}
}
public abstract class GeneralTask
{
protected GeneralTask()
{
}
public string Title { get; set; }
public int ClientId { get; set; }
public virtual Client Client { get; set; }
}
But I get the below error.
Error Message :"The query specified in the URI is not valid. The property 'Client' cannot be used in the $expand query option."
Any help would be appreciated.

We need to enable OData Model Bound Attributes which you can do globally with the middle line in the following block(WebApiConfig.cs file)
ODataModelBuilder builder = new ODataConventionModelBuilder();
config.Count().Filter().OrderBy().Expand().Select().MaxTop(null); //new line
builder.EntitySet<DB.Project>("Projects");

Related

LINQ: How to filter collection by data in related table

I have two Entity Framework Core entities:
public class JobOrder {
public int Id { get; set; }
public string JobTitle { get; set; }
public string Status { get; set; }
...
public IEnumerable<JobOrderUser> JobOrderUsers { get; set; }
}
public class JobOrderUser {
public int AppUserId { get; set; }
public AppUser User { get; set; }
public int JobOrderId { get; set; }
public JobOrder JobOrder { get; set; }
}
The second one is a join table used for a many-to-many between the JobOrder and User tables but I don't need to drill to the User table for this.
I want to get a collection of JobOrders that have an association with a specific user. In SQL, I would write something like this:
select distinct
a.*
from
JobOrders a
join JobOrderUser b on a.JobOrderID = b.JobOrderId
where
b.AppUserId = someId
How do I do that using LINQ method syntax?
If your entities are set up correctly, and their relationships are intact, you could load the JobOrderUsers while querying for a JobOrder and then filter by a user. Something like
JobOrder.Include(t => t.JobOrderUsers).Where(t => t.JobOrderUsers.Any(x => x.User.Id == SomeId));
You can also use the below query using join and Select the required columns data in a jobOrdersDto class. For that, you have to inject the _jobOrdersRepository and _jobOrderUserRepository repositories to your service where you are calling the required method.
var result = (from jobOrders in _jobOrdersRepository.GetAll()
join jobOrderUser in _jobOrderUserRepository.GetAll() on jobOrders.JobOrderID equals jobOrderUser.JobOrderId
where
(jobOrderUser.AppUserId == someId)
select new jobOrdersDto
{
}
Your Service class:
public class YourService
{
private readonly IRepository<jobOrders> _jobOrdersRepository;
private readonly IRepository<jobOrderUser> _jobOrderUserRepository;
public YourService(
IRepository<jobOrders> jobOrdersRepository, IRepository<jobOrderUser> jobOrderUserRepository)
: base()
{
_jobOrdersRepository = jobOrdersRepository;
_jobOrderUserRepository = jobOrderUserRepository;
}
}

Telerik OpenAccess - Mapping Varchar to Int

I'm trying to run an integer comparison (for instance greater than or less than) using OData on a value that is set to be a type of varchar in the database. Crossing out the solution of changing the database field to be a type of int, as it's not preferred in my specific case, is there a way to tell Telerik OpenAccess to convert the field to a type of integer when executing either the query or the mappings?
Thanks in advance.
It is similar with this one: Handling Dates with OData v4, EF6 and Web API v2.2
Add one more proerpty:
public partial class Title
{
public int Id { get; set; }
public string Name { get; set; }
public string StringProperty { get; set; }
}
public partial class Title
{
[NotMapped]
public int IntProperty
{
get
{
return StringProperty==null?0;Int32.Parse(StringProperty);;
}
set
{
StringProperty = value.ToString();
}
}
}
Update the model:
public static IEdmModel GetModel()
{
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
EntityTypeConfiguration<Title> titleType= builder.EntityType<Title>();
titleType.Ignore(t => t.StringProperty);
titleType.Property(t => t.IntProperty ).Name = "MyProperty";
builder.EntitySet<Title>("Titles");
builder.Namespace = typeof(Title).Namespace;
return builder.GetEdmModel();
}

MongoDB C# driver and MVC4 webapi. Issue in json serialization

I am using MongoDB database with MVC4 WebAPI using the C# driver provided by MongoDB. I have a an issue with serialization. I get the following error,
"ExceptionMessage=Error getting value from '__emptyInstance' on 'MongoDB.Bson.ObjectId'"
If I change the Content-Type to xml in my HTTP request it just works fine. I would appreciate any help.
I have copied the model below.
public class Subscriber
{
public ObjectId _id;
public long SubscriberId { get; set; }
public Name Name { get; set; }
public Address Address { get; set; }
public string Phone { get; set; }
public ICollection<Subscription> Subscription { get; set; }
public Subscriber()
{
Name = new Name();
Address = new Address();
Subscription = new Collection<Subscription>();
}
}
Solution
Converting _id type string and decorating the field as below did the trick
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string _id;
reference: JSON.NET cast error when serializing Mongo ObjectId
For anyone trying the mentioned "solution" in the answer : It simply doesn't work!
Check the marked answer in this, instead.

Linq trowing Exceptions

I create a project where I use EF with LINQ and Model first. So, based on my edmx I created my Database and also my classes.
So I got some problems. I created a Click to test if my code is working.
protected void btnSearch_Click(object sender, EventArgs e)
{
ZUser Zusr = new ZUser();
List<ZUser> lst = Zusr.ListAll();
// Zusr.Id = 1;
string test = "";
foreach (ZUser item in lst)
{
test = item.Name;
}
lblName.Text = test;
}
So in my ZUser Class (Controller) I did the following code:
[Serializable]
public class ZUser : User
{
String connString = ConfigurationManager.ConnectionStrings["ConnectionString"].ToString();
public List<ZUser> ListAll()
{
List<ZUser> lstUser = new List<ZUser>();
using (DataContext db = new DataContext(connString))
{
Table<User> Users = db.GetTable<User>();
var query =
from usr in Users
where usr.Name == "Test"
select usr;
foreach (ZUser usr in query)
lstUser.Add(usr);
}
return lstUser;
}
}
And my Model (Class generated by my edmx)
namespace System.Model
{
//[Table]
public partial class User
{
public int Codigo { get; set; }
public string Name { get; set; }
public string LastName { get; set; }
public string Password { get; set; }
public DateTime Created { get; set; }
public DateTime LastLogin { get; set; }
}
}
Problems
If I don't let the [Table] in my Model class (I added that) I got this error. I'm not sure if this is the right way to correct it.
The type '{0}' is not mapped as a Table.
After "fixing" the problem from above. I got this new one in my foreach (ZUser usr in query).
The member '{0}.{1}' has no supported translation to SQL.
I don't know how to fix or create a workaround this one.
Amazing, this feature of linq!
Really intresting!
After some searches on msdn and test it in application,
maybe you miss the Column attribute over all single class members:
[Column(CanBeNull = false, DbType = "int")]
And maybe you must uncomment the Table attribute on top of User declaration
Hope this help!

MongoDB - Condition on sub documents using Linq

I'm using the mongo-csharp-driver to query my Mongo entities.
I have the following objects which are stored in the Mongo:
public class Table
{
public int Id { get; private set; }
public string Description{ get; private set; }
public List<Player> Players { get; private set; }
public Table()
{
}
}
public class Player
{
public int Id { get; private set; }
public string Username{ get; private set; }
public Player()
{
}
}
When I'm trying to query the "Table" object by id or description, I get the appropriate results, but when I try to query by the list of player, I get null:
// Works ok
var tab1 = mongo.GetCollection<Table>().Where(g => g.Description == "Test");
// Always return null, although should return the same result
var tab2 = mongo.GetCollection<Table>().Where(g => g.Players.Count > 90).FirstOrDefault();
What am I missing here?
Thanks,
Nir.
The issue is that Count property is translated into the $size query operator.
From the linked Advanced Queries page you can see that:
"You cannot use $size to find a range of sizes (for example: arrays
with more than 1 element)."

Resources