I had a look at Entity Framework, get object by ID.
I can't get that to work.
I specifically want the
WHERE [Extent1].[CatId] = 1
as I don't want to return everything that filter it as in
using (ApplicationContext db = new ApplicationContext())
{
IQueryable<Project> projects = db.Projects; // Get all
var p = (from i in db.Projects where i.Id == ProjectID select i);
Console.WriteLine("Project # {0} added and Named:{1} ", ProjectID, p.First().Name);
Assert.IsNotNull(projects.First().Name);
}
So what I am looking for in SQL terms is
SELECT *
FROM Projects
WHERE id = 1
Hope that makes sense.
You should be able to use LINQ fluent syntax:
var project = db.Projects.SingleOrDefault(i => i.Id == ProjectId);
Great LINQ reference and examples
Related
I am using below code to join two tables based on officeId field. Its retuning 0 records.
IQueryable<Usage> usages = this.context.Usage;
usages = usages.Where(usage => usage.OfficeId == officeId);
var agencyList = this.context.Agencies.ToList();
var usage = usages.ToList();
var query = usage.Join(agencyList,
r => r.OfficeId,
a => a.OfficeId,
(r, a) => new UsageAgencyApiModel () {
Id = r.Id,
Product = r.Product,
Chain = a.Chain,
Name = a.Name
}).ToList();
I have 1000+ records in agencies table and 26 records in usage table.
I am expecting 26 records as a result with chain and name colums attached to result from agency table.
Its not returning anything. I am new to .net please guide me if I am missing anything
EDIT
#Tim Schmelter's solution works fine if I get both table context while executing join. But I need to add filter on top of usage table before applying join
IQueryable<Usage> usages = this.context.Usage;
usages = usages.Where(usage => usage.OfficeId == officeId);
var query = from a in usages
// works with this.context.usages instead of usages
join u in this.context.Agencies on a.OfficeId equals u.OfficeId
select new
{
Id = a.Id,
Product = a.Product,
Chain = u.Chain,
Name = u.Name
};
return query.ToList();
Attaching screenshot here
same join query works fine with in memory data as you see below
Both ways works fine if I add in memory datasource or both datasource directly. But not working if I add filter on usages based on officeId before applying join query
One problem ist that you load all into memory first(ToList()).
With joins i prefer query syntax, it is less verbose:
var query = from a in this.context.Agencies
join u in this.context.Usage on a.OfficeId equals u.OfficeId
select new UsageAgencyApiModel()
{
Id = u.Id,
Product = u.Product,
Chain = a.Chain,
Name = a.Name
};
List<UsageAgencyApiModel> resultList = query.ToList();
Edit: You should be able to apply the Where after the Join. If you still don't get records there are no matching:
var query = from a in this.context.Agencies
join u in this.context.Usage on a.OfficeId equals u.OfficeId
where u.OfficeId == officeId
select new UsageAgencyApiModel{ ... };
The following code can help to get the output based on the ID value.
Of course, I wrote with Lambda.
var officeId = 1;
var query = context.Agencies // your starting point - table in the "from" statement
.Join(database.context.Usage, // the source table of the inner join
agency => agency.OfficeId, // Select the primary key (the first part of the "on" clause in an sql "join" statement)
usage => usage.OfficeId , // Select the foreign key (the second part of the "on" clause)
(agency, usage) => new {Agency = agency, Usage = usage }) // selection
.Where(x => x.Agency.OfficeId == id); // where statement
I am converting the C# linq query to SQL, LINQ never return the values.
But the same query I wrote in SQL returns some values. Can anyone help me find out what the issue is for my SQL query?
LINQ query:
var query = from l in _DbContext.Licenses
join lp in _DbContext.LicenseParts on l.PartNumber equals lp.PartNumber
join lpc in _DbContext.LicensePartConfigurations on lp.Id equals lpc.LicensePartId
join p in _DbContext.Products on lp.ProductId equals p.Id
join lsn in _DbContext.LicenseSerialNumbers on l.Id equals lsn.LicenseId
join lact in _DbContext.LicenseActivations on new { a = lsn.Id, b = lp.ProductId } equals new { a = lact.LicenseSerialNumberId, b = lact.ProductId }
where lact.AccountId == AccountId && JsonExtensions.JsonValue(lact.ActivationInfoJSON, "$.SubscriptionKey") !=
" " && (JsonExtensions.JsonValue(lact.ActivationInfoJSON, "$.IsConverted") == null || JsonExtensions.JsonValue(lact.ActivationInfoJSON, "$.IsConverted") == "0" || JsonExtensions.JsonValue(lact.ActivationInfoJSON, "$.IsConverted") == "false") && p.Name == "ClearPass Legacy"
select new SubscriptionKeys { SubscriptionKey = JsonExtensions.JsonValue(lact.ActivationInfoJSON, "$.SubscriptionKey"), CustomerMail = JsonExtensions.JsonValue(lact.ActivationInfoJSON, "$.CustomerMail"), CustomerName = JsonExtensions.JsonValue(lact.ActivationInfoJSON, "$.CustomerName") };
response.PageSize = pageSize;
response.PageNumber = pageNumber;
response.Model = await query.Distinct().ToListAsync();
response.ItemsCount = response.Model.Count();
SQL query:
SELECT
l.AccountId,CustomerMail,
JSON_VALUE(ActivationInfo, '$.SubscriptionKey')
FROM
Licenses l
JOIN
LicenseParts lp ON l.PartNumber = lp.PartNumber
JOIN
LicensePartConfigurations lpc ON lp.Id = lpc.LicensePartId
JOIN
Products p ON lp.ProductId = p.Id
JOIN
LicenseSerialNumbers lsn ON l.Id = lsn.LicenseId
JOIN
LicenseActivations lact ON lsn.Id = lact.LicenseSerialNumberId
AND lp.ProductId = lact.ProductId
WHERE
lact.AccountId = 'QWNjb3VudDoxNTMwNDAzMi00MWM2LTExZTktOWYzMy1kMzQxZjE5OWZlYjM='
AND JSON_VALUE(lact.ActivationInfo, '$.SubscriptionKey') != ' '
AND (JSON_VALUE(lact.ActivationInfo, '$.IsConverted') = NULL OR
JSON_VALUE(lact.ActivationInfo, '$.IsConverted') = 0 OR
JSON_VALUE(lact.ActivationInfo, '$.IsConverted') = 'false')
AND p.Name = 'ClearPass Legacy'
To start from a valid point, execute the code where it fires this linq query and use sql profiler to catch it up. That is a good way to find the exact equivalent sql statement it finally produces and executes. You need to set up a trace to sql profiler prior to execute the linq. Get the statement and then you can compare with the sql you already have.
this sql:
(JSON_VALUE(lact.ActivationInfo, '$.IsConverted') = NULL
is not equal to:
(JsonExtensions.JsonValue(lact.ActivationInfoJSON, "$.IsConverted") == null
as in first case you compare to database NULL value using '=' and this requires ansi_nulls off to work properly and it is not a good practice.
ORMs like EF Core are meant to Map Objects to Relational constructs. Instead of trying to write SQL in C# through LINQ, you should try to Map the attributes you need to entity properties.
In this case the SubscriptionKey and IsConverted fields should appear in the table itself, either as proper fields or computed columns. If that's not possible, you could use computed columns to map the SubscriptionKey and IsConverted attributes to entity properties so you can use them in queries.
In your LicenseActivation class add these properties:
public bool? IsConverted {get;set;}
public string? SubscriptionKey {get;set;}
public string? CustomerEmail {get;set;}
In your DbContext, you can specify computed columns with HasComputedColumnSql:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<LicenseActivation>()
.Property(b => b.SubscriptionKey)
.HasComputedColumnSql("JSON_VALUE(ActivationInfo, '$.SubscriptionKey')");
modelBuilder.Entity< LicenseActivations >()
.Property(b => b.IsConverted)
.HasComputedColumnSql("JSON_VALUE(ActivationInfo, '$.IsConverted')");
modelBuilder.Entity< LicenseActivations >()
.Property(b => b.CustomerEmail)
.HasComputedColumnSql("JSON_VALUE(ActivationInfo, '$.CustomerEmail')");
}
This will allow you to use the properties in LINQ queries.
You shouldn't have to use all those JOINs either. It's the ORM's job to generate JOINs from the relations between objects. If you add proper relations between the entities the query could be simplified to :
var binValue='QWNjb3VudDoxNTMwNDAzMi00MWM2LTExZTktOWYzMy1kMzQxZjE5OWZlYjM=';
var query=_dbContext.LicenseActivations
.Where(lact=>
lact.AccountId == binValue
&& (lact.IsConverted==null || !lact.IsConverted))
.Select(lact=>new {
lact.AccountId,
lact.SubscriptionKey,
lact.CustomerEmail});
or, if the AccountId fields don't hold the same data :
.Select(lact=>new {
AccountId =lact.LicensePart.License.AccountId,
lact.SubscriptionKey,
lact.CustomerEmail
});
EF Core will generate the appropriate SQL and JOIN clauses to get from LicenseActivation to License based on the relations between the entities
I have a query which I ran successfully in SQL Server Management Studio, which returns the table values shown in the screenshot
The query I used is:
SELECT tcoid, COUNT(*) ownleasetank
FROM TankProfile
WHERE ownleasetank = 3
GROUP BY tcoid
Now I'm using Entity Framework to make things easier in my sample project.
I used this method to return the table values as array object:
public async Task<Object> GetLeaseInformationPrincipal()
{
ISOTMSEntities context = new ISOTMSEntities();
var testleaseinfo = from d in context.TankProfiles
join f in context.TankOperators
on d.tcoid equals f.tcoId
where (d.ownleasetank == 3)
select new { f.tcoName, d.ownleasetank } into x
group x by new { x.tcoName } into g
select new
{
tconame = g.Key.tcoName,
ownleasetank = g.Select(x => x.ownleasetank).Count()
};
return testleaseinfo.ToList();
}
but it is not working properly. I also tried other ways, when I use where and groupby method in Entity Framework it doesn't working properly for me.
Does anybody know the solution for this?
It's very simple with LINQ methods:
context.TankProfiles
.Where(t => t.ownleasetank = 3)
.GroupBy(t => t.tcoid)
.Select(g => new {g.Key, g.Count()})
.ToArray();
I have no idea why in your C# version of the query you have such opeartions such join, while your SQL query is very simple. You have to rethink that :)
var c = from t in context.TankProfile
where t.ownleasetank == 3
group t by t.tcoid into g
select new { tcoid=g.Key, ownleasetank=g.Select(x => x.ownleasetank).Count() };
return c.ToList();
How do I get randomly similar data
me tried to merge different ones in the first stage but Different function does not work,
var turler= (from x in db.bird_table_ad
join e in db.kus_resim on x.tr_x equals e.kus_tur
where x.aile == item
select new GozlemTurleri
{
id = x.id,
kod = x.kod,
tr_x = x.tr_x,
en_x = x.en_x,
lt_x = x.lt_x,
turfotourl="image_resize.phpad="+e.altDIR+"/"+e.resim+"&yon="+(e.galeri=="fg"?"2":"HD2"),
aile = x.aile,
gfoto = x.gfoto
}).Distinct().ToList();
If you try to get distinct record with regarding to tr_x from database then you can use GroupBy in entity framework.
So your code will be.
.GroupBy(x => x.tr_x).Select(x => x.First()).ToList();
Instead of
.Distinct().ToList();
List<HelprClass.Organizer> org =
( from EventOrg in cntx.EventOrganizer
from MstrOrg in cntx.Organizer
where EventOrg.OrganizerID == MstrOrg.OrganizerID
Select new HelprClass.Organizer
{
OrganizerName = MstrOrg.OrganizerName
}).ToList()
This work fine now i want to use IN Opeartor in the above Query.
in the EventOrganizer I have EventID now i want to select only Event ID exsist in EventOrganizer collection
I have EventID another var varibale
Var EventID= From EvntID in Evetn Select new {ID= EvntID.EventID};
Something like this
where
EventOrg.OrganizerID == MstrOrg.OrganizerID
&& EventOrg.EventID in EventID.ID
How I can achive this ?
I will appreciate your help
Try this:
var EventIDs = from EvntID in Event select EvntID.EventID;
var org = (from EventOrg in cntx.EventOrganizer
from MstrOrg in cntx.Organizer
where EventOrg.OrganizerID == MstrOrg.OrganizerID
select new {E=EventOrg, M=MstrOrg}
).ToList();
org = org
.Where(o => EventIDs.Contains(o.E.EventID) )
.Select(o => new HelprClass.Organizer
{
OrganizerName = o.M.OrganizerName
}
);
If you are using Entity Framework you can not use a Contains statement, which would be an easy solution in Linq. SO if it's just Linq 2 Entities, use a where clause like "where EventId.Contains(EventOrg.Id)"
If you are indeed using Entity Framework you will have to build an or expression based on the Id's in the EventID Collection.