I have a channel and i would like to remove some users. I have used code from WTelegramClient to get all the participants, but for some reason it is only returning 200? We have 31k members.
Here is the code i am using to get participants, which is the same as on the examples.
var deleted = new List<User>();
var bannedRights = new ChatBannedRights();
bannedRights.flags = 0;// ChatBannedRights.Flags.change_info | ChatBannedRights.Flags.embed_links | ChatBannedRights.Flags.invite_users | ChatBannedRights.Flags.pin_messages | ChatBannedRights.Flags.send_games | ChatBannedRights.Flags.send_gifs | ChatBannedRights.Flags.send_inline | ChatBannedRights.Flags.send_media | ChatBannedRights.Flags.send_messages | ChatBannedRights.Flags.send_polls | ChatBannedRights.Flags.send_stickers | ChatBannedRights.Flags.view_messages;
// now loop through our tweets
for (int offset = 0; ;)
{
var participants = await client.Channels_GetParticipants(channel, null, offset, 100, accessHash);
for (var i = 0; i < participants.users.Count; i++)
{
var participant = (ChannelParticipant)participants.participants[i];
var member = (User)participants.users[participant.user_id];
if (participant.date.Year == _joinedOn.Year && participant.date.Month == _joinedOn.Month && participant.date.Day == _joinedOn.Day)
{
Console.Write(string.Format("Removing user '{0}' as joined on {1}...", member.username, _joinedOn));
await client.Channels_EditBanned(channel, member, bannedRights);
deleted.Add(member);
}
}
offset += participants.participants.Length;
if (offset >= participants.count) break;
}
I am guesing there is a server restriction or something? Much help appreciated
This is due to a Telegram server-side enforced limitation that restrict to only 200 members when querying the list of members on some (big) groups/channels.
There is now a new method in WTelegramClient that work-around this limit and tries to get all the participants in the channel:
var participants = await client.Channels_GetAllParticipants(channel);
It can take a few minutes to complete for big channels/groups and will likely not be able to obtain the full list of participants but it will go beyond that 200 or 10k member limit
I would like to know is if I have an excel file and I am trying to get data via linq query will this be posible?
Excel file format
+-----------------+-------------+
| Inputlocation | Inputvalue |
+-----------------+-------------+
| 1 | Hello |
+-----------------+-------------+
| 2 | World!!! |
+-----------------+-------------+
Now If I am using Linq query given below is it possible to get Inputvalue data
var fileName = #"C:\Users\jshah\Documents\Visual Studio 2013\Projects\QA_ExpScript\QA_ExpScript\Excel\Inputdata.xls";
string sheetName = "Input";
var book = new LinqToExcel.ExcelQueryFactory(fileName);
var users = from x in book.Worksheet(Input) select x;
foreach (var x in users)
{
Console.WriteLine(x["1"]);
}
I am trying to do here is where inputlocation is "1" give me Inputvalue which is "Hello". Am I on a correct way to specify the query?. Also I am using this again and again later in my code. So please give better solution for this.
You can use where clause to filter the data like this:-
var users = from x in book.Worksheet()
where x["Inputlocation"].Cast<int>() == 1
select x["Inputvalue"].Cast<string>();
Then you can simply iterate through users:-
foreach (var item in users)
{
Console.WriteLine(item.Inputvalue); //This will print "Hello"
}
Although IMHO its always better to create a matching type to avoid any exceptions that can occur by typos when specifying the column names.
public class User
{
public int Inputlocation { get; set; }
public string Inputvalue { get; set; }
}
and here is the query:-
var users = from x in book.Worksheet<User>()
where x.Inputlocation == 1
select x;
This is kinda same as I am doing but somewhat answering the question. But don't what which #RahulSingh is saying.
Also related to #Chris 1 in the code. And creator of this post is i think saying that he does not want to change anythhing in his function. The only change he wants is Console.WriteLine(x["1"]); or Console.WriteLine(x["2"]); to get Inputvalue
Reference to my post
So I have a simple key-value table BillTypes in my SQL Server. It looks like this:
+----+-------------+
| Id | Description |
+----+-------------+
| 1 | OK |
| 2 | Missing |
| 3 | Maximum |
| 4 | Minimum |
| 5 | Error |
+----+-------------+
The table holds different types of bill states. I have another table Items with a foreign key BillType, referring to Id in the previous table.
+----------+------+--------+
| IdItem | Cash |BillType|
+----------+------+--------+
| * | * | * |
| * | * | * |
| * | * | * |
| ... |... | ... |
+----------+------+--------+
Then, in my application I get data from the second table via a stored procedure. In this sp, I am not sure if should select the BillType as it is, a tinyint, or use an innerjoin to return the description instead. The thing is, my application has some logic depending on the BillType, i.e. rows will be processed differently depending on the BillType. Should my logic depend on the Id or the description??
In code, should I have something like this?
DataTable dt = ...//call stored procedure that selects the BillType id
foreach(Datarow r in dt)
{
if(r["BillType"] == 3) ... //use logic
}
or this?
DataTable dt = ...//call stored procedure that selects the BillType description
foreach(Datarow r in dt)
{
if(r["BillType"] == "Maximum") ... //use logic
}
I am currently using the second way, with descriptions, because I think it makes code more readable. I am however worried about the possibility that someone might change the descriptions and break my application logic. On the other hand, using ids would be less readable(though i could work around this with an enum) and would be invulnerable to description changes, but still if someone changed an id, things would break.
To be honest, we don't expec anyone to mess around with the first table, since we made it specially for this application. Still, I am new to SQL and I am trying to learn the best practices of application-SQL interaction, so I would like to know how experienced people do it
Please consider this a comment rather than an answer (I don't yet have enough rep to comment).
I prefer the latter (as you are doing), where I rely on the description.
If your IDs are SQL indentity fields (which auto-increment) Consider the following scenario:
You build your app and database in DEV environment
The production deployment gets back out and re-run
Now, rather than IDs 1,2,3 you have 4,5,6
Generally speaking, it makes more sense to rely on IDs instead of values. After all, IDs should be unique, whereas values can have duplicates/change. Although you are not expecting any changes to the BillTypes table, I wouldn't use the string values, as you suggested.
Since updates/deletes/inserts can still happen in the BillTypes table and you want to be prepared as well as have readable code, the easiest thing to do would be if you define your own enum as such:
public Enum BillTypesEnum
{
OK = 1,
Missing = 2,
Maximum = 3,
Minimum = 4,
Error = 5
};
If something happens and you need to add something to the database, you do it and then change the Enum. It would also work if you delete the "Error" entry and insert "Average". You would not get Average=5 but probably Average=6 or something higher. The enum structure lets you define the values with no problem.
Then you can use it all over your code, not just in this single instance. Your code is modified below:
DataTable dt = ...//call stored procedure that selects the BillType id
foreach(Datarow r in dt)
{
if(r["BillType"] == (int)BillTypesEnum.Maximum) ... //use logic
}
This makes the code more readable then before, you dont have to hard-code the values all over your code but just in one place. And if it happens,that you will not be changing the database, then it's just a plus.
Another option would be to do the spGetAllBillTypes (select * from tblBillTypes) and then internally create a dictionary.
Dictionary<string,int> dictBillTypes = new Dictionary<string,int>();
int = billTypeId
string = billTypeText
When you retrieve your data from the child table (the one with the foreign key), you retrieve your billtypetext.
You can then do it like this:
DataTable dt = ...//call stored procedure that selects the BillType id
foreach(Datarow r in dt)
{
if(r["BillType"] == dictBillTypes["Maximum"]) ... //use logic
}
...but this is still an incomplete solution, because here, you rely on two things:
1. that the billTypeText will not change (if it does, you have to change it in the code)
2. that the billTypeText will not have duplicates (otherwise you will get an exception about duplicate key value in the dictionary)
Another option is to turn it around:
Dictionary<int,string> dict = new Dictionary<int,string>();
and do the search based on the value instead of the key. But that makes the code less readable and you dont really gain a lot from this.
If you are worried about the ID changing, I would recommend creating an Abstract Class to hold the ID values. This can be referenced like an Enum, and it will look up the ID on the first call, and cache the result:
public abstract class BillType
{
private static readonly string c_ok = "ok";
private static readonly string c_missing = "missing";
private static readonly string c_maximum = "maximum";
private static readonly string c_minimum = "minumum";
private static readonly string c_error = "error";
private static int? _ok = null;
private static int? _missing = null;
private static int? _maximum = null;
private static int? _minimum = null;
private static int? _error = null;
public static int OK
{
get
{
if (_ok == null)
_ok = GetBillTypeID(c_ok);
return (int)_ok;
}
}
public static int Missing
{
get
{
if (_missing == null)
_missing = GetBillTypeID(c_missing);
return (int)_missing;
}
}
public static int Maximum
{
get
{
if (_maximum == null)
_maximum = GetBillTypeID(c_maximum);
return (int)_maximum;
}
}
public static int Minimum
{
get
{
if (_minimum == null)
_minimum = GetBillTypeID(c_minimum);
return (int)_minimum;
}
}
public static int Error
{
get
{
if (_error == null)
_error = GetBillTypeID(c_error);
return (int)_error;
}
}
private static int GetBillTypeID(string identifier)
{
using (SqlConnection conn = new SqlConnection("your connection string")
{
conn.Open();
using (SqlCommand cmd = new SqlCommand("spGetBillTypeId", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("Description", identifier);
return Convert.ToInt32(cmd.ExecuteScalar());
}
}
}
}
I would also have a Stored Procedure on your database to do a lookup for that ID:
Create Procedure spGetBillTypeId (#Description Varchar (20))
As Begin
Select Id
From BillTypes
Where Description = #Description
End
With this, you can simply call BillType.Missing and it will pull the Id of missing, cache it, and return 2.
(Note, most of this was copy/paste, so mind random errors I didn't catch).
If you don't expect the values to change, however, and you are okay with making code changes if that does happen, you can simply make an Enum:
public enum BillType
{
OK = 1,
Missing = 2,
Maximum = 3,
Minimum = 4,
Error = 5
}
How to compare everytime, the current record with the previous record in the same table using MySQL C# in MVC3.0.
This is my table
Historytable:
id | projid| task | name | description | date | type
----|-------| ----- | -------------- |------------ | -------| ---------
1 | 1 | sys21 | validation | validating user | 1-5-12 | created
2 | 1 | sys21 | bug tracking | background bug | 23-7-12 | updated
| | | | tracking | |
3 | 1 | sys21 | bug tracking | bug reporting | 30-8-12 | updated
4 | 1 | sys21 | bugs | bug reporting | 12-9-12 | updated
----------------------------------------------------------------------------------
now i want the result such that compare the record of type updated with the previous record in order to show the previous record as the previous history and record obtained by comparing with the previous record and display only the updated fields as the current history.
now depending upon the projid retrieve the history.
and my view look like the below:
previous history current history
---------------- ---------------
type: created
name: validation
description: validating user
--------------------------------------------------------------
type: created updated
name validation bug tracking
description: validating user background bug tracking
--------------------------------------------------------------------
type: updated updated
name: bug tracking bug report
description: background bug tracking bug reporting
----------------------------------------------------------------
type: updated updated
name: bug tracking -
Description: background bug tracking bug reporting
------------------------------------------------------------------------
type: updated updated
name: bug tracking bugs
Description: bug reporting -
I am expecting the above output, any one plz help me out from the situation,
any king of sugesions will be accepted...
Thankyou,
I am not sure I understood you correctly but you could approach this with the following logic:
Get the rows that represent the history of an item and order by date descending
Get the first row from above as the last change
Get the second row from 1. as the previous to last change
Compare the data
Here's a potential approach for this (using Linq):
var history = db.History.Where(item => item.ProjId == 1)
.OrderByDescending(item => item.Date);
var lastChange = history.First();
var previousChange = history.Skip(1).First();
Now you need to send the above rows to your comparison method. If you want to highlight the changes, you can iterate through properties of the rows and compare values for same properties like this:
private IEnumerable<Tuple<string, object, object>> GetChangesBetweenRows(History row1, History row2)
{
var result = new List<Tuple<string, object, object>>();
var properties = lastChange.GetType().GetProperties(); // both rows are of the same type
foreach(var propInfo in properties)
{
var obj1 = propInfo.GetValue(lastChange, null);
var obj2 = propInfo.GetValue(previousChange, null);
if(obj1 != obj2)
result.Add(Tuple.Create(propInfo.Name, obj1, obj2));
}
return result;
}
EDIT
Given the method above, you can iterate through a collection of history rows and get differences between any of two rows in the collection:
static void Main(string[] args)
{
var history = db.History.Where(item => item.ProjId == 1)
.OrderBy(item => item.Date)
.ToArray();
for(int i=1; i<history.Length; i++)
{
var diff = GetChangesBetweenRows(history[i-1], history[i]);
DisplayDifferences(diff);
}
}
static void DisplayDifferences(IEnumerable<Tuple<string, object, object>> diff)
{
foreach(var tuple in diff)
{
Console.WriteLine("Property: {0}. Object1: {1}, Object2: {2}",tuple.Item1, tuple.Item2, tuple.Item3);
}
}
I have two tables that are linked n-n. And I have a method that takes one object and saves.
public int Save(Table1 element)
{
using (var database = new Entities())
{
if (element.ID == 0)
{
database.Table1.AddObject(element);
}
else
{
database.Attach(element); //
database.ObjectStateManager.GetObjectStateEntry(element).SetModified();
database.Refresh(RefreshMode.ClientWins, element);
}
return database.SaveChanges();
}
}
When I don't try to modify obj1.Table2 it attaches and saves successfully. But if I try to modify this EntityCollection
element.Table2.Add(tb2);
And save, I get the following error:
An object with a temporary EntityKey value cannot be attached to an object context.
at Line: database.Attach(element);
How can I fix it?
Database:
Table 1 Table 2
ID | Name ID | Name
--------- -------------------
1 | One 1 | Related to One
2 | Two 2 | Related to One
3 | Three
Table 3
Tb1 | Tb2
---------
// 1 | 1
// 1 | 2
Creating Table1 object:
var element = GetTable1Obj(1);
element.Table2.Add(GetTable2Obj(1)); // GetTable2Obj uses a separated context
element.Table2.Add(GetTable2Obj(2)); // like Save method to return the object
provider.Save(element); // Method above
If Your Entity frame work model is set to something like this You should be able to modify t1 or t2 without having issues. while still keeping
From the looks of table 3 in your example you don't have a key for the entries.
Which will cause issues when modifying the Entity Object. What is your DB Fk set at.