Check if ICollection contains an element based on a property [duplicate] - c#

This question already has answers here:
What does Collection.Contains() use to check for existing objects?
(6 answers)
Closed 4 years ago.
In C-Sharp I have a Registrations class which basically creates a list of Questions items like this:
public partial class Registrations
{
public Registrations()
{
this.Questions = new HashSet<Questions>();
}
public int id { get; set; }
public virtual ICollection<Questions> Questions { get; set; }
}
My Questions class has a field called Title and it just gives the form field label.
public partial class Questions
{
public int id { get; set; }
public int registrationId { get; set; }
public string Title { get; set; }
public string Data { get; set; }
}
When a user creates a registration, he can add many questions with different titles. I want to check if a specific registration has a field with the title "City". I want to create a function in my Registrations class called hasCity which will return a boolean depending if the specific registration has that field.
public hasCity()
{
Questions city = new Questions();
city.Title = "City";
if( this.Questions.Contains( city ) )
{
return true;
}
return false;
}
Now, the function above always returns false and I am guessing it is because I need to create some kind of method to check only the Title attribute for the string value City.

I think you can use Any method in LinQ for this. Try the following. Hope to help, my friend:
public partial class Questions
{
public int id { get; set; }
public int registrationId { get; set; }
public string Title { get; set; }
public string Data { get; set; }
}
public partial class Registrations
{
public Registrations()
{
this.Questions = new HashSet<Questions>();
}
public int id { get; set; }
public virtual ICollection<Questions> Questions { get; set; }
public bool HasCity(string titleCity)
{
if (this.Questions.Any(x => x.Title.ToLower() == titleCity.ToLower()))
{
return true;
}
return false;
}
}

Related

How to populate object with another object with almost same structure? [duplicate]

This question already has answers here:
copy chosen properties to object of other type
(2 answers)
How to cast between 2 types of the same name and internal sturcture but from different assemblies?
(5 answers)
Copy two identical object with different namespaces (recursive reflection)
(7 answers)
Closed 2 years ago.
I'm trying to find the best way to populate my constructor with another constructor that have almost the same structure without setting each attribute,
So i have constructor Altridatiidentificativi in ModelRA constructor:
public class Altridatiidentificativi
{
public string denominazione { get; set; }
public string indirizzo { get; set; }
public string numeroCivico { get; set; }
public string cap { get; set; }
public string comune { get; set; }
public string provincia { get; set; }
public string nazione { get; set; }
public bool modificati { get; set; }
public string defAliquotaIVA { get; set; }
public bool nuovoUtente { get; set; }
}
And Altridatiidentificativi in Documenti:
public class Altridatiidentificativi
{
public bool nuovoUtente { get; set; }
public string denominazione { get; set; }
public string indirizzo { get; set; }
public string numeroCivico { get; set; }
public string cap { get; set; }
public string comune { get; set; }
public string provincia { get; set; }
public string nazione { get; set; }
}
As you can see the structure is almost the same, just constructor in ModelRA has this two extras modificati and defAliquotaIVA
So i was wondering if it's possible in some way to pass inside ModelRA.Altridatiidentificativi the Documenti.Altridatiidentificativi and then add the value to the extras
I was trying to do something like this :
public ModelRA initializeRA(Documento documento)
{
ModelRA model = new ModelRA();
model.altriDatiIdentificativi = <Altridatiidentificativi>(documento.altriDatiIdentificativi);
model.altriDatiIdentificativi.defAliquotaIVA = "";
model.altriDatiIdentificativi.modificati = false;
return model;
}
but i get error in <Altridatiidentificativi> "it's a type not a valid constructor in specific context"
Is there a way to reach what i'm trying to do or i have to set all the attributes manually?
Usually this pattern is a signal that there's a concept in your business model that needs to be abstracted into a composable pattern. The ModelRA.Altridatiidentificativi class could look like:
public class Altridatiidentificativi
{
public ModelRA.Altridatiidentificativi ModelRAAltridatiidentificativi { get; set; }
public bool modificati { get; set; }
public string defAliquotaIVA { get; set; }
}
Then your initialization code could look like this:
public ModelRA initializeRA(Documento documento)
{
ModelRA model = new ModelRA();
model.altriDatiIdentificativi.ModelRAAltridatiidentificativi = documento;
model.altriDatiIdentificativi.defAliquotaIVA = "";
model.altriDatiIdentificativi.modificati = false;
return model;
}
Tangentially I should mention that it's usually good practice to use property initializers and constructors unless you have a specific reason that you need initialization methods.
public class Altridatiidentificativi
{
public string ModelRA.Altridatiidentificativi ModelRAAltridatiidentificativi { get; set; }
public bool modificati { get; set; } = false; // unnecessary: this is default.
public string defAliquotaIVA { get; set; } = "";
public Altridatiidentificativi(ModelRA.Altridatiidentificativi modelRAAltridatiidentificativi)
{
this.modelRAAltridatiidentificativi = ModelRAAltridatiidentificativi;
}
}

Invoking child nodes Entity Framework Core

I'm new into this sort of object programming, do you mind helping me?
I have to invoke the child nodes, but specific fields, but I can't figure out how to do that. I have already looked into a huge number of places, but it doesn't seem to work.
For example, I want just the FirstName in the RepunicAccount, and all the other info from RepunicAccountType, or anything like it.
My DbContext:
public class RepunicContext : DbContext
{
public virtual DbSet<RepunicAccount> RepunicAccount { get; set; }
public virtual DbSet<RepunicAccountType> RepunicAccountType { get; set; }
protected override void OnConfiguring (DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer ("Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=Repunic;Data Source=DESKTOP- 6I8LD45\\SQLEXPRESS_ERICH");
}
public RepunicContext (DbContextOptions<RepunicContext> options) :base (options)
{ }
public RepunicContext () { }
}
My model class:
public class RepunicAccount
{
public int ID { get; set; }
public string Email { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
[ForeignKey ("ID_Type")]
public int? ID_Type { get; set; }
public ICollection<RepunicAccountType> TipoConta { get; set; }
public DateTime? DataCadastro { get; set; } = DateTime.Now;
public DateTime? DataAlteracao { get; set; } = DateTime.Now;
}
My child node class:
public class RepunicAccountType
{
[Key]
public int ID_Type { get; set; }
public string Descricao { get; set; }
public DateTime DataCadastro { get; set; } = DateTime.Now;
public DateTime DataAlteracao { get; set; } = DateTime.Now;
}
I have a repository, that is where I do my coding, before putting into the controller, it's pretty much the same in every place, but I'm going to show the example that I'm trying to use in both places.
public IEnumerable<RepunicAccount> GetAllByIDType ()
{
var data = db.RepunicAccount.Where (a => a.ID_Type != null)
.Include (p => p.types);
var type = db.RepunicAccountType.OrderBy (b => b.Descricao);
return data.ToList();
}
The problem is: I dont know how to invoke specific items nor make anything else other thanToList();`
So, what should I do? If there is any more info that I can send, just ask me.
I would love to comment however, I do not have the required reputation to do so.
Since you are new to the subject please be sure to follow the documentation.
EF Core Documentation
I also have created a youtube video for getting started that I would suggest you take a few minutes to view.
Video on EF Core
in short, you need a DBContext and your Models. You then can start a query for data and returning in the format you wish. Like so:
using (var context = new RepunicContext())
{
var accounts = context.RepunicAccounts.ToList();
}
accounts will then have a list of every account that you can iterate through. Hope this helps.

Linq to sql query with Parent child relationship

I have following model for posting the question and replies to the question
Model
public partial class LMS_Question
{
[Key]
public int ClassDiscussionID { get; set; }
public int? ParentClassDiscussionID { get; set; }
public string Discussion { get; set; }
public string DiscussionTitle { get; set; }
}
When user will post new question the 'ParentClassDiscussionID' will be null and if any reply added to the question then 'ClassDiscussionID' will be updated to 'ParentClassDiscussionID'.
Basically ClassDiscussionID and ParentClassDiscussionID columns have parent-child relationship.
However, I want to show the data like DiscussionTitle,ReplyCount as follows
DiscussionTitle ReplyCount
-------------------------
Question1 2 Reponses
Question2 3 Reponses
Question3 5 Reponses
So, how can I achieve this using linq to sql query ?
Thanks for the help !
First of all you need to change your model to something like this
public partial class LMS_ClassDiscussion
{
public LMS_ClassDiscussion()
{
LMS_ClassDiscussionchild = new List<LMS_ClassDiscussion>();
}
public int ClassDiscussionID { get; set; }
public int? ParentClassDiscussionID { get; set; }
public string Discussion { get; set; }
public string DiscussionTitle { get; set; }
public LMS_ClassDiscussion _LMS_ClassDiscussion { get; set; }
public List<LMS_ClassDiscussion> LMS_ClassDiscussionchild { get; set; }
}
then you need method to get all children of parents
public List<LMS_ClassDiscussion> GetChildren(IList<LMS_ClassDiscussion> source, int? parentId)
{
var children = source.Where(x => x.ParentClassDiscussionID == parentId).ToList();
//GetChildren is called recursively again for every child found
//and this process repeats until no childs are found for given node,
//in which case an empty list is returned
children.ForEach(x => x.LMS_ClassDiscussionchild = GetChildren(source, x._LMS_ClassDiscussion.ClassDiscussionID));
return children.ToList();
}
call method this way
var LMS_ClassDiscussions = GetChildren(query, null);
foreach (var item in LMS_ClassDiscussions)
{
Console.WriteLine(item._LMS_ClassDiscussion.ClassDiscussionID + "="+item.LMS_ClassDiscussionchild.Count);
}

C# Linq search inside object linked property

i'm trying to do some search inside some attributes of my object set but i'm getting some trouble on the right way to mount my linq query, i have my VT_Video class which has its attributes and some linked objects
public partial class VT_Video
{
public int ID { get; set; }
public string title { get; set; }
public string description { get; set; }
public virtual ICollection<VT_VideoTag> VT_VideoTag { get; set; }
}
public partial class VT_VideoTag
{
public int ID { get; set; }
public int tagID { get; set; }
public int videoID { get; set; }
public virtual VT_Tag VT_Tag { get; set; }
public virtual VT_Video VT_Video { get; set; }
}
public partial class VT_Tag
{
public int ID { get; set; }
public string name { get; set; }
public virtual ICollection<VT_VideoTag> VT_VideoTag { get; set; }
}
What i want to accomplish is search a user given word inside my Video collection by VT_Video.title, VT_Video.description and also by VT_Video.VT_VideoTag.VT_Tag.name, what i managed to do so far is only search the title and description:
var myVideos = db.VT_Video.Include("VT_VideoTag")
.Include("VT_VideoTag.VT_Tag")
.Where(vid =>
vid.descricao.Contains(strBusca) ||
vid.titulo.Contains(strBusca)).ToList();
Now, i know i can do what i want with some foreach and extra code but i wondered if it would be possible to do it using linq and also keep my code clean.
Thanks.
I have not worked with LINQ to SQL much, but it seems like .Any() would satisfy your requirement:
var myVideos = db.VT_Video.Include("VT_VideoTag")
.Include("VT_VideoTag.VT_Tag")
.Where(vid =>
vid.descricao.Contains(strBusca) ||
vid.titulo.Contains(strBusca) ||
vid.VT_VideoTag.Any(tag => tag.name.Contains(strBusca))).ToList();
Notice I added this clause:
vid.VT_VideoTag.Any(tag => tag.name.Contains(strBusca))
Which returns true if any tag in the collection has a name that contains your search string.

Updating List<T> in DbContext

I have a Model like this
public class Challenge
{
public int ID { get; set; }
public string Name { get; set; }
public string Blurb { get; set; }
public int Points { get; set; }
public string Category { get; set; }
public string Flag { get; set; }
public List<string> SolvedBy { get; set; }
}
public class ChallengeDBContext : DbContext
{
public DbSet<Challenge> Challenges { get; set; }
}
and then Controller like this. But I cannot update the List "SolvedBy", the next time I step through with the debugger, the list is still empty.
[HttpPost]
public string Index(string flag = "", int id=0)
{
Challenge challenge = db.Challenges.Find(id);
if (flag == challenge.Flag)
{
var chall = db.Challenges.Find(id);
if (chall.SolvedBy == null)
{
chall.SolvedBy = new List<string>();
}
chall.SolvedBy.Add(User.Identity.Name);
db.Entry(chall).State = EntityState.Modified;
db.SaveChanges();
//congrats, you solved the puzzle
return "got it";
}
else
{
return "fail";
}
}
is there any way around it to make a list of strings kept in the database?
EF don't know how to store an array in database table so it just ignore it. You can create another table/entity or use XML/JSON to store the list. You can serialize the list before saving and deserialize it after loading from database
A List<T> in a model would normally map to a second table, but in your DbContext you only have a single table. Try adding a second table.
public class ChallengeDBContext : DbContext
{
public DbSet<Challenge> Challenges { get; set; }
public DbSet<Solution> Solutions {get; set;}
}
public class Challenge
{
public int ID { get; set; }
public string Name { get; set; }
public string Blurb { get; set; }
public int Points { get; set; }
public string Category { get; set; }
public string Flag { get; set; }
public List<Solution> SolvedBy { get; set; }
}
public class Solution
{
public int ID { get; set; }
public string Name { get; set; }
}
Then your controller can use code along the lines of...
var chall = db.Challenges.Find(id);
if (chall.SolvedBy == null)
{
chall.SolvedBy = new List<Solution>();
}
chall.SolvedBy.Add(new Solution {Name=User.Identity.Name});
None of the above has been tested and I may have made some mistakes there, but the general principle I want to illustrate is the fact that you need another table. The List<T> represents a JOIN in SQL.

Categories

Resources