Entity Frame Navigation property for table joins - c#

I have 3 tables namely Ship[ShipID, Name, YearOfConstr, CompanyID(FK), TypeID(FK)] which is a bridge between Company[CompanyID, Name, Headquarter] and Type[TypeID, Description, NoPassengers]
I wanted to query the names of all Company which has a specific type = "xxx" and whose headquater = "yyy"
Below is what I have tried, but it's returning nothing and won't throw an error either.
public List<string> AllShippingCompanies(string TypeDescription, string headquarters)
{
var list = from shipcomany in dbContext.Ships.Where(x => x.Type.Description == TypeDescription && x.ShippingCompany.Headquarter == headquarters)
select shipcomany.ShippingCompany.Name;
return list.ToList();
}
What could I have been doing wrong ?

I just check and found there are no related data in my DB. The code works fine. It's correct. Thanks for your time

Related

How to save an Id into a variable in EntityFrameworkCore and SQLite

I am very new to the Entity Framework Core and working with SQL
I have created a table called 'User' in a database and everytime I a new user is created, a new Id is also generated since it is a primary key. I want to be able save the users Id when they login, so that if they add a new workout to the workout table, then it will be saved with their Id.
I have tried:
foreach (var field in data)
{
if (context.User.Any(user => user.Name == UserName && user.Password == PassWord))
{
int UserID = context.User.Any(user => user.Id = UserID);
}
But I still don't exactly know how the queries work
Please help me.
"Any" returns a boolean.
https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.any?view=net-6.0
So the .Any in your first statement is "technically ok", but you end up doing 2 checks to find the object (your "User")....and your second Any doesn't seem correct.
See the below:
https://www.learnentityframeworkcore.com/dbset#retrieving-an-entity
So you might want to try FirstOrDefault
(the below is a modified version that comes from the "learnentityframeworkcore" website above.
int primaryKey = 0;
using (SampleContext context = new SampleContext())
{
Author foundAuthor = context.Authors.FirstOrDefault(a => a.LastName == "Shakespeare");
if (null != foundAuthor)
{
primaryKey = foundAuthor.AuthorKey;
}
}
You can also try
SingleOrDefault
where the "Single" will throw an exception if more than 1 row is found. (Your code as-is has a pitfall of finding more than one match....maybe you have a unique-constraint on username...but it isn't shown here.
Sidenotes:
your "for" loop .. looks very dangerous. how many times are you checking for the matching userid?
keeping passwords as plain text in your database is a HORRIBLE/DANGEROUS/SECURITY-ISSUE.
Don't use .Any, use .FirstOrDefault and check for null.
If your user is not null, you may access the Id property

Linq to Dataset C#

So I have a table called groupe_stg it contains 2 foreign keys code_demande , code_stagiaire and at the same time they are primary keys.
In my app I have the code_stagiaire and from it I want to retrieve it's code_demande. Basically what am trying to say is:
select code_demande
from group_stg
where code_stagiaire = "parameter"`
I would've create a stored procedure it would be easier , but unfortunately I was forced to work with an access database
This is my solution for the LINQ code,
String code_linq()
{
var query = from g in Program.mds.group_stg
where g.cin_stagiaire == txt_cin.Text
select new
{
code = g.code_demande
};
return query.ToString();
}
As you can see it is some sort a scalar function
but this code is giving me this exception:
system.data.enumerablerowcollection'1 [<>
f_anonymousType0'1[System.String]]
You are selecting multiple code_demande in an anonymous type but you want a single string.
If you just want the first code_demande which has cin_stagiaire == txt_cin.Text:
var demands = from g in Program.mds.group_stg
where g.cin_stagiaire == txt_cin.Text
select g.code_demande;
return demands.FirstOrdefault(); // null if no match

How can I use a where clause and check if a string variable contains in a many table column

I have made an method that will check if name value contains in the name column on current table, but I also need to see if the name contains in another column that is in a many table(TABLE.Project).
TABLE.Customer 1 --- *(many) TABLE.Project(Which have column named "Name")
This is the method:
Public List<SearchObject> Finditem(string name)
{
var query = from o in db.tbl_Custommer
where o.Name.Contains(name)
select new SearchObject
{
Url = o.tbl_Webs.WebUrlName,
Name = o.Name,
};
return query.ToList();
}
Do I need to iterate throught each o.Project?
Any kind of help is appreciated alot!
presuming you have the relationship correctly setup and its called Projects then you could use any - i.e. return customers where the name matches name and they have at least one project with the name also matching:
var query = from o in db.tbl_Custommer
where o.Name.Contains(name) && o.Projects.Any(p => p.Name.Contains(name))
select new SearchObject
{
Url = o.tbl_Webs.WebUrlName,
Name = o.Name,
};

cannot "Add or Update" Entity because Primery key cannot be changed

I am implementing an import routine, where a user pastes a specific formatted string into an input field, which in turn gets tranformated into an entity and then put into a database.
The algorithm checks if the entity already exists and either tries to update it or insert it into the database. Inserting works fine - updating fails.
//considered existing if Name and owning user match.
if (db.Captains.Any(cpt => cpt.Name == captain.Name && cpt.User.Id == UserId))
{
var captainToUpdate = db.Captains.Where(cpt => cpt.Name == captain.Name && cpt.User.Id == UserId).SingleOrDefault();
db.Entry(captainToUpdate).CurrentValues.SetValues(captain);
db.Entry(captainToUpdate).State = EntityState.Modified;
await db.SaveChangesAsync();
}
The problem at hand is, that written like this, it tries to update the primary key as well, (captain Id is 0, whereas captainToUpdate Id is already set) which results in an exception The property 'Id' is part of the object's key information and cannot be modified.
What do I need to change, so the enttiy gets updated properly. If it can be avoided I don't want to update every property by hand, because the table Captain contains 30ish columns.
What you can do is first set the Id of captain to be the same as the Id of captainToUpdate:
captain.Id = captainToUpdate.Id;
db.Entry(captainToUpdate).CurrentValues.SetValues(captain);
await db.SaveChangesAsync();
I would not use the entity Captain to transfer the data to the UI, but a DTO object that has all properties you want to copy and no more. You can copy values from any object. All matching properties will be copied, all other properties in captainToUpdate will not be affected.
Try something like this ?
var captainToUpdate = db.Captains.FirstOrDefault(cpt => cpt.Name == captain.Name && cpt.User.Id == UserId);
if(captainToUpdate != null){//Update captain Here
captainToUpdate.Update(captain);
}else{//Create captain here
db.Captains.Add(captain);
}
db.Savechanges();
I had the same issue and solved it by extension method and reflection, of course it will be better to create standalone class with some cachning for relfection, but performance wasn't critical in my task.
public static class EnitityFrameworkHelper
{
public static void SetValuesByReflection(this DbPropertyValues propertyValues, object o, IEnumerable<string> properties = null)
{
var reflProperties = o.GetType().GetProperties();
var prop = properties ?? propertyValues.PropertyNames;
foreach (var p in prop)
{
var refp = reflProperties.First(x => x.Name == p);
var v= refp.GetValue(o);
propertyValues[p] = v;
}
}
}
and here is example how to use it
var entry = ctx.Entry(accSet);
entry.CurrentValues.SetValuesByReflection(eParameters, entry.CurrentValues.PropertyNames.Except(new [] { "ID"}));
Also be careful with foreign keys in object which you want to update, probably you want to exclude them too.

How do I extract this LinqToSql data into a POCO object?

with my Repository classes, I use LinqToSql to retrieve the data from the repository (eg. Sql Server 2008, in my example). I place the result data into a POCO object. Works great :)
Now, if my POCO object has a child property, (which is another POCO object or an IList), i'm trying to figure out a way to populate that data. I'm just not too sure how to do this.
Here's some sample code i have. Please note the last property I'm setting. It compiles, but it's not 'right'. It's not the POCO object instance .. and i'm not sure how to code that last line.
public IQueryable<GameFile> GetGameFiles(bool includeUserIdAccess)
{
return (from q in Database.Files
select new Core.GameFile
{
CheckedOn = q.CheckedOn.Value,
FileName = q.FileName,
GameFileId = q.FileId,
GameType = (Core.GameType)q.GameTypeId,
IsActive = q.IsActive,
LastFilePosition = q.LastFilePosition.Value,
UniqueName = q.UniqueName,
UpdatedOn = q.UpdatedOn.Value,
// Now any children....
// NOTE: I wish to create a POCO object
// that has an int UserId _and_ a string Name.
UserAccess = includeUserIdAccess ?
q.FileUserAccesses.Select(x => x.UserId).ToList() : null
});
}
Notes:
Database.Files => The File table.
Database.FilesUserAccess => the FilesUserAccess table .. which users have access to the GameFiles / Files table.
Update
I've now got a suggestion to extract the children results into their respective POCO classes, but this is what the Visual Studio Debugger is saying the class is :-
Why is it a System.Data.Linq.SqlClient.Implementation.ObjectMaterializer<..>
.Convert<Core.GameFile> and not a List<Core.GameFile> containing the POCO's?
Any suggestions what that is / what I've done wrong?
Update 2:
this is what i've done to extract the children data into their respective poco's..
// Now any children....
UserIdAccess = includeUserIdAccess ?
(from x in q.FileUserAccesses
select x.UserId).ToList() : null,
LogEntries = includeUserIdAccess ?
(from x in q.LogEntries
select new Core.LogEntry
{
ClientGuid = x.ClientGuid,
ClientIpAndPort = x.ClientIpAndPort,
// ... snip other properties
Violation = x.Violation
}).ToList() : null
I think that all you need to do is to put another Linq query in here:
q.FileUserAccesses.Select(x => x.UserId).ToList()
i.e. You want to select data from the FileUserAccess records - which I'm assuming are Linq to SQL classes, so to do this you can have something like:
(from fua in q.FileUserAccesses
select new PocoType
{
UserID = fua.UserID,
Name = fua.User.UserName // Not sure at this point where the name comes from
}).ToList()
That should get you pointed in the right direction at least.
What is the type of UserIdAccess? How is it not 'right'? Are you getting the 'wrong' data? if so have you checked your database directly to make sure the 'right' data is there?

Categories