PaginatedList for pagination for MVC 3 application? Error: has some invalid arguments - asp.net-mvc-3

I have the following code, I can figure why its invalid argument:
AuditDAL ad = new AuditDAL();
var agencies = ad.SearchAgencies("Ak001", "");
string col = param.sColumns.Split(',')[param.iSortCol_0];
string orderby = col + " " + param.sSortDir_0;
// The best overloaded method match for 'AMS.Helper.PaginatedList.PaginatedList(System.Linq.IQueryable, int, int)' has some invalid arguments C:\NexGen\AMS\DEV\Source\AMS\Controllers\AuditController.cs
var qry = new PaginatedList<AuditAgency>(agencies, param.iDisplayStart, param.iDisplayLength);
PaginatedList Code:
namespace AMS.Helper
{
public class PaginatedList<T> : List<T> {
public int PageIndex { get; private set; }
public int PageSize { get; private set; }
public int TotalCount { get; private set; }
public int TotalPages { get; private set; }
public PaginatedList(IQueryable<T> source, int pageIndex, int pageSize) {
PageIndex = pageIndex;
PageSize = pageSize;
TotalCount = source.Count();
TotalPages = (int) Math.Ceiling(TotalCount / (double)PageSize);
this.AddRange(source.Skip(PageIndex * PageSize).Take(PageSize));
}
public bool HasPreviousPage {
get {
return (PageIndex > 0);
}
}
public bool HasNextPage {
get {
return (PageIndex+1 < TotalPages);
}
}
}
}
Search Agencies Code:
public IEnumerable<AuditAgency> SearchAgencies(string ori, string name)
{
List<AuditAgency> agencies = new List<AuditAgency>();
using (var conn = new SqlConnection(_connectionString))
{
var com = new SqlCommand();
com.Connection = conn;
com.CommandType = CommandType.StoredProcedure;
string term = "Ori";
if (!String.IsNullOrEmpty(ori))
{
term = "Ori";
com.Parameters.Add(new SqlParameter
{
ParameterName = "#ORI",
Value = ori
});
}
if (!String.IsNullOrEmpty(name))
{
term = "legal_name";
com.Parameters.Add(new SqlParameter
{
ParameterName = "#Name",
Value = name
});
}
com.CommandText = "Audit_Get_Agency_List";
var adapt = new SqlDataAdapter();
adapt.SelectCommand = com;
var dataset = new DataSet();
adapt.Fill(dataset);
agencies = (from c in dataset.Tables[0].AsEnumerable()
select new AuditAgency()
{
Agency_ID = Convert.ToInt32(c["Agency_Id"]),
Agency_Name = c["Agency_Name"].ToString(),
Agency_Ori = c["ORI"].ToString(),
COPSAuditNumber = c["COPSAuditNumber"].ToString(),
OIGAuditNumber = c["OIGAuditNumber"].ToString()
}).ToList<AuditAgency>();
return agencies;
}
}

The error should tell you where to start.
If you fire up the debugger, I think you'll find agencies is an IEnumberable, but not an IQueryable
correct it by changing the return type of SearchAgencies from IQueryable to IEnumerable
or alternatively, you can change the type of the PaginatedList to accept IEnumberables instead of IQueryables. this may be safer as IQueryable inherits from IEnumerable
(see
http://msdn.microsoft.com/en-us/library/system.linq.iqueryable.aspx or
Differences between IQueryable, List, IEnumerator?
for the difference between the two)

Related

How to bind Data Grid in DevExpress Xamarin

Generate headers like so:
public void ClearDataGrid()
{
this.xDataGrid.ItemsSource = null;
//// [Grid Headr 초기 세팅]
//this.xDataGrid.Columns.Clear();
//this.m_Model.MeasureData.Clear();
this.xDataGrid.Columns.Clear();
//// [Wave header 생성]
//Column cNo = GridUtil.Instance.SetColumn(ColumnTypes.Text, "No", "No", new ColumnWidth() { Value = 75 });
//this.xDataGrid.Columns.Add(cNo);
DevExpress.XamarinForms.DataGrid.TextColumn cNo = GridUtil.Instance.SetColumn(ColumnTypes.Text, "No", "No", 75) as DevExpress.XamarinForms.DataGrid.TextColumn;
this.xDataGrid.Columns.Add(cNo);
// [파장값 입력]
for (int i = 0; i < this.m_Model.WaveLength.Count; i++)
{
string strID = string.Empty;
if ((DisplayDataType)Enum.Parse(typeof(DisplayDataType), this.m_Model.DisplayDataUnitType.ToString()) == DisplayDataType.ABS)
{
strID = string.Format("ABS[{0}]", i);
DevExpress.XamarinForms.DataGrid.NumberColumn Col = GridUtil.Instance.SetColumn(
ColumnTypes.Numeric,
strID,
string.Format("A[{0}]", this.m_Model.WaveLength[i]),
150) as DevExpress.XamarinForms.DataGrid.NumberColumn;
this.xDataGrid.Columns.Add(Col);
}
else
{
strID = string.Format("Trans[{0}]", i);
DevExpress.XamarinForms.DataGrid.NumberColumn Col = GridUtil.Instance.SetColumn(
ColumnTypes.Numeric,
strID,
string.Format("T[{0}]", this.m_Model.WaveLength[i]),
150) as DevExpress.XamarinForms.DataGrid.NumberColumn;
this.xDataGrid.Columns.Add(Col);
}
}
DevExpress.XamarinForms.DataGrid.TextColumn cCell = GridUtil.Instance.SetColumn(ColumnTypes.Text, "Cell", "Cell", 75) as DevExpress.XamarinForms.DataGrid.TextColumn;
DevExpress.XamarinForms.DataGrid.DateColumn cDateTime
= GridUtil.Instance.SetColumn(ColumnTypes.Date, "Date", "Date", 150) as DevExpress.XamarinForms.DataGrid.DateColumn;
this.xDataGrid.Columns.Add(cCell);
this.xDataGrid.Columns.Add(cDateTime);
this.xDataGrid.ItemsSource = this.m_Model.MeasureData;
}
When a button is clicked, temporary data is created and added to the bound model.
private async void BtnMeasureClick(object sender, EventArgs e)
{
PhotometricMeasureData data = new PhotometricMeasureData();
++nIndex;
data.No = nIndex.ToString();
data.Cell = string.Format("C[{0}]", nIndex);
data.DateTime = DateTime.Now;
for (int i = 0; i < this.m_Model.WaveLength.Count; i++)
{
data.OriginABS.Add(new Random().Next(-10, 10));
data.OriginTrans.Add(new Random().Next(-10, 10));
data.ABS.Add(data.OriginABS[i] * this.m_Model.Factor);
data.Trans.Add(data.OriginTrans[i] * this.m_Model.Factor);
}
this.m_Model.MeasureData.Add(data);
//this.xDataGrid.Columns[0].Pinned = PinnedPositions.Left;
//this.xDataGrid.ScrollToLastRowByIndex(this.m_Model.MeasureData.Count-1);
}
binding model
public BindingList<PhotometricMeasureData> MeasureData
{
set; get;
} = new BindingList<PhotometricMeasureData>();
public class PhotometricMeasureData : INotifyPropertyChanged
{
//List<float> m_lstABS = new List<float>();
//List<float> m_lstTrans = new List<float>();
public string No { get; set; }
public string Cell { get; set; }
public DateTime DateTime { get; set; }
public BindingList<float> ABS
{
get; set;
} = new BindingList<float>();
public BindingList<float> Trans
{
get; set;
} = new BindingList<float>();
public BindingList<float> OriginABS
{
get; set;
} = new BindingList<float>();
public BindingList<float> OriginTrans
{
get; set;
} = new BindingList<float>();
public void UpdateABSByFactor(float factor)
{
//this.ABS.Clear();
for (int i = 0; i < this.ABS.Count; i++)
{
this.ABS[i] = this.OriginABS[i] * factor;
OnPropertyChanged(string.Format("ABS[{0}]", i));
}
}
public void UpdateTransByFactor(float factor)
{
//this.Trans.Clear();
for (int i = 0; i < this.Trans.Count; i++)
{
this.Trans[i] = this.OriginTrans[i] * factor;
OnPropertyChanged(string.Format("Trans[{0}]", i));
}
}
public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
In the current bound model, No and Cell DateTime are binding fine.
But the data created by BindingList is not being bound.
When creating a column in the header, the field name was created and inserted like string.Format("ABS[{0}]", i).
And I tried to bind the data accessed by the index of the ABS list of the binding model.
But it doesn't work as well as I thought.
What am I doing wrong?
enter image description here
enter image description here

Page displays everything that is in the database

The PageSize field indicates that information should be displayed on one page, about eight objects, but the page displays everything that is in the database.
private readonly IObjectRepository _objectRepository;
private readonly IWebHostEnvironment hostingEnvironment;
public int PageSize = 8;
public HomeController(IObjectRepository objectRepository, IWebHostEnvironment hostingEnvironment)
{
_objectRepository = objectRepository;
this.hostingEnvironment = hostingEnvironment;
}
public ViewResult Index(int objectPage)
{
var model = _objectRepository.GetAllObjects();
model.OrderBy(o => o.Id)
.Skip((objectPage - 1) * PageSize)
.Take(PageSize);
return View(model);
}
Skip and Take return a new IEnumerable as a result, instead of modifying the existing one in place. So, you should replace this line:
model.OrderBy(o => o.Id)
.Skip((objectPage - 1) * PageSize)
.Take(PageSize);
with:
model=model.OrderBy(o => o.Id)
.Skip((objectPage - 1) * PageSize)
.Take(PageSize);
This way, you assign the new query value to the baseQuery and then when you enumerate it, it will return the expected entities.
Thanks everyone! I found another solution with Methanit, thanks him a lot.
1 - Changed my PageViewModel
public class PageViewModel
{
public int PageNumber { get; set; }
public int TotalPages { get; set; }
public PageViewModel(int count, int pageNumber, int pageSize)
{
PageNumber = pageNumber;
TotalPages = (int)Math.Ceiling(count / (double)pageSize);
}
public bool HasPreviousPage
{
get
{
return (PageNumber > 1);
}
}
public bool HasNextPage
{
get
{
return (PageNumber < TotalPages);
}
}
}
2 - Changed method Index in Controller:
public IActionResult Index(int page = 1)
{
int pageSize = 6;
var model = _objectRepository.GetAllObjects();
var count = model.Count();
var items = model.Skip((page - 1) * pageSize).Take(pageSize).ToList();
PageViewModel pageViewModel = new PageViewModel(count, page, pageSize);
IndexViewModel viewModel = new IndexViewModel
{
PageViewModel = pageViewModel,
Objects = items
};
return View(viewModel);
}
3 - The application is working correctly.
Thanks all a lot!

LINQ Searching ordered list and appending occurence number

I have the following custom class
public class Album
{
public string PhotoName { get; set; }
public string Location { get; set; }
public DateTime DateTime { get; set; }
}
and I have the following string:
#"photo.jpg, Warsaw, 2013-09-05 14:08:15
john.png, London, 2015-06-20 15:13:22
myFriends.png, Warsaw, 2013-09-05 14:07:13
Eiffel.jpg, Paris, 2015-07-23 08:03:02
pisatower.jpg, Paris, 2015-07-22 23:59:59
BOB.jpg, London, 2015-08-05 00:02:03"
and I need to write a function that will append the order number beside the Location based on the timestamp thus the resulting StringBuilder must be
Warsaw01.jpg
London01.jpg
Warsaw02.jpg
Paris01.jpg
Paris02.jpg
London02.jpg
What I have done so far?
I have a List of that type that I sorted by Location then by DateTime
List<Album> SortedList = list
.OrderBy(o => o.Location)
.ThenBy(o => o.DateTime)
.ToList();
now I need to have a StringBuilder that will append the index number beside the location.
This is my complete method with the part and I am stuck on how should I search the ordered list. Question is: how can I write the LINQ for searching through the list?:
public static string Solution(string S)
{
string[] group = S.Split("\r\n");
List<Album> list = new List<Album>();
StringBuilder sb = new StringBuilder();
//added each line of the string to list
foreach (string g in group)
{
string[] album = g.Split(',');
Album a = new Album();
a.PhotoName = album[0];
a.Location = album[1];
a.DateTime = DateTime.Parse(album[2]);
list.Add(a);
}
//ordered the list
List<Album> SortedList = list.OrderBy(o => o.Location).ThenBy(o => o.DateTime).ToList();
//then foreach line, append index number by searching through the list
foreach (string g in group)
{
string[] album = g.Split(',');
Album a = new Album();
a.PhotoName = album[0];
string[] photodetails = a.PhotoName.Split('.');
a.Location = album[1];
a.DateTime = DateTime.Parse(album[2]);
//this is the part where I must figure out how to build the string. I am stuck here
// var query = SortedList.IndexOf(list.SingleOrDefault(i => i.DateTime == a.DateTime));
sb.AppendLine(a.Location + query + "." + photodetails[1]);
}
string res = sb.ToString();
return res;
}
Appreciate the responses.
Update Warsaw2 must appear before Warsaw1 since the timestamp of Warsaw2 is later than Warsaw1
Warsaw02.jpg
London01.jpg
Warsaw01.jpg
Paris01.jpg
Paris02.jpg
London02.jpg
I have just added a order in the Album class
public class Album
{
public string PhotoName { get; set; }
public string Location { get; set; }
public DateTime DateTime { get; set; }
public int Order { get; set; }
}
public static string Solution(string S)
{
string[] stringSeparators = new string[] { "\r\n" };
string[] group = S.Split(stringSeparators, StringSplitOptions.None);
List<Album> list = new List<Album>();
StringBuilder sb = new StringBuilder();
//added each line of the string to list
for (int i = 0; i < group.Length; i++)
{
string[] album = group[i].Split(',');
Album a = new Album();
a.PhotoName = album[0];
a.Location = album[1];
a.DateTime = DateTime.Parse(album[2]);
a.Order = i;
list.Add(a);
}
//ordered the list
var groupedByLocation = list.GroupBy(o => o.Location).ToList();
for (int i = 0; i < groupedByLocation.Count; i++)
{
int indexValue = 01;
foreach (var item in groupedByLocation[i])
{
item.PhotoName = string.Format("{0}{1}.jpg", groupedByLocation[i].Key, indexValue);
indexValue++;
}
}
//then foreach line, append index number by searching through the list
var locations = groupedByLocation
.SelectMany(g => g.Select(h => h))
.ToList()
.OrderBy(y => y.Order)
.Select(g => g.PhotoName);
return string.Join("\r\n", locations);
}
Just for the fun - an alternative approach:
For the task at hand, there's no need to have an Album class, a list and two loops.
We can go over the lines once, and use a dictionary to hold the counters for us.
class PhotoLocationsCounter
{
private readonly Dictionary<string, int> locationsCounter = new Dictionary<string, int>();
public string GetLocationsWithCounters(string source)
{
string[] lines = source.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
var locations = lines.Select(this.LineToLocationWithCounter);
return string.Join("\n", locations);
}
private string LineToLocationWithCounter(string line)
{
string[] album = line.Split(',');
var location = album[1].Trim();
var ext = album[0].Split('.')[1];
var counter = this.GetAndIncreaseLocationCounter(location);
return $"{location}{counter.ToString("D2")}.{ext}";
}
private int GetAndIncreaseLocationCounter(string location)
{
if (!this.locationsCounter.TryGetValue(location, out int counter))
{
this.locationsCounter.Add(location, 0);
}
return ++this.locationsCounter[location];
}
}
And you call it:
string data = #"photo.jpg, Warsaw, 2013-09-05 14:08:15
john.png, London, 2015-06-20 15:13:22
myFriends.png, Warsaw, 2013-09-05 14:07:13
Eiffel.jpg, Paris, 2015-07-23 08:03:02
pisatower.jpg, Paris, 2015-07-22 23:59:59
BOB.jpg, London, 2015-08-05 00:02:03";
var locations = new PhotoLocationsCounter().GetLocationsWithCounters(data);

PLSQL parsing using Oracle.VsDevTools.SqlAndPlsqlParser

I downloaded Oracle Developer Tools for Visual studio and explored the libraries (.dll). I need to parse the PLSQL scripts to get the SQL Statements in that and using the visitors to visit the nodes. I found Oracle.VsDevTools.SqlAndPlsqlParser library and explored further and tried to parse the PLSQL scripts. Please refer the below code.
string plSQLScript="CREATE TABLE Student(Age int);";
List<LexerToken> tokens= LexerToken.Parse(plSQLScript, false, true);
But the above code gives tokens only, I need PLSQL parser.
Is there any possible way to parser the PLSQL scripts and get the sql statements. Also I need to explicit visit the sql statements like CreateTableVisitor, CreateProcedureVisitor, etc.
I already created the parser for TSQL files by exploring Microsoft SQL library called Microsoft.SqlServer.TransactSql.ScriptDom and using the below mentioned code for parsing.
TSql100Parser parser = new TSql100Parser(true);
IList<ParseError> error;
using (TextReader tr = new StreamReader(filePath))
{
TSqlFragment fragment = parser.Parse(tr, out error);
tr.Close();
}
And using TSqlFragmentVisitor to visit the sql statements. Please refer the below mentioned code.
public override void ExplicitVisit(CreateTableStatement node)
{
//----Coding----
}
I want the same for PLSQL by using Oracle.VsDevTools.SqlAndPlsqlParser library.
Please let me know if there any possibility for this.
Thanks,Sivaprakash.
With some reflection used it's possible. The parser, nodes and grammar classes are internal. I made small example for you:
private static Assembly odacDevAssembly = Assembly.Load("Oracle.VsDevTools.14.0");
private static Type parseNodeType = odacDevAssembly.GetType("Oracle.VsDevTools.SqlAndPlsqlParser.ParseNode");
void Main()
{
var parserType = odacDevAssembly.GetType("Oracle.VsDevTools.SqlAndPlsqlParser.OracleSqlEarley");
var parser = Activator.CreateInstance(parserType);
const string sqlScriptText = "DECLARE x NUMBER; BEGIN SELECT DUMMY INTO :DUMMY FROM DUAL T1; x := 1; SELECT DUMMY INTO :DUMMY FROM DUAL T2; x := 2; INSERT INTO T3 (C) VALUES (1); x := 3; END;";
var tokens = LexerToken.Parse(sqlScriptText);
var parserGrammar = parserType.GetProperty("EarleyGrammar").GetValue(parser);
var allSymbols = (string[])parserGrammar.GetType().GetField("m_vAllSymbols", BindingFlags.Public | BindingFlags.Instance).GetValue(parserGrammar);
var sqlStatementIndex = -1;
for (var i = 0; i < allSymbols.Length; i++)
{
if (allSymbols[i] == "unlabeled_nonblock_stmt")
{
sqlStatementIndex = i;
break;
}
}
var parseTree = parserType.GetMethod("Parse").Invoke(parser, new object[] { sqlScriptText, tokens });
//parseTree.GetType().GetMethod("PrintTree", new Type[] { parserGrammar.GetType() }).Invoke(parseTree, new object[] { parserGrammar });
var commandNodes = GetDescendants(parseTree).Where(d => GetPayloadIn(d) == sqlStatementIndex);
foreach (var commandNode in commandNodes)
{
var commandText = GetCommandText(commandNode, sqlScriptText, tokens);
Console.WriteLine(commandText);
}
}
private static string GetCommandText(object parseNode, string sqlScriptText, List<LexerToken> tokens)
{
var from = (int)parseNodeType.GetProperty("From").GetValue(parseNode);
var to = (int)parseNodeType.GetProperty("To").GetValue(parseNode) - 1;
var begin = tokens[from].m_vBegin;
return sqlScriptText.Substring(begin, tokens[to].m_vEnd - begin);
}
private static IEnumerable<object> GetDescendants(object parseNode)
{
yield return parseNode;
foreach (var child in GetChildren(parseNode))
foreach (var descendant in GetDescendants(child))
yield return descendant;
}
private static int GetPayloadIn(object parseNode)
{
return (int)parseNodeType.GetProperty("PayloadIn").GetValue(parseNode);
}
private static IEnumerable<object> GetChildren(object parseNode)
{
return (IEnumerable<object>)parseNodeType.GetMethod("Children").Invoke(parseNode, null);
}
UPDATE:
I'm not exactly sure what do you want to achieve but I hope it will be at least somehow helpful:
private static Assembly odacDevAssembly = Assembly.Load("Oracle.VsDevTools.14.0");
private static Type parseNodeType = odacDevAssembly.GetType("Oracle.VsDevTools.SqlAndPlsqlParser.ParseNode");
void Main()
{
var parserType = odacDevAssembly.GetType("Oracle.VsDevTools.SqlAndPlsqlParser.OracleSqlEarley");
var parser = Activator.CreateInstance(parserType);
const string sqlScriptText = "DECLARE x NUMBER; BEGIN SELECT DUMMY INTO :DUMMY FROM DUAL T1; x := 1; SELECT DUMMY INTO :DUMMY FROM DUAL T2; x := 2; INSERT INTO T3 (C) VALUES (1); x := 3; END;";
var tokens = LexerToken.Parse(sqlScriptText);
var parserGrammar = parserType.GetProperty("EarleyGrammar").GetValue(parser);
var allSymbols = (string[])parserGrammar.GetType().GetField("m_vAllSymbols", BindingFlags.Public | BindingFlags.Instance).GetValue(parserGrammar);
const int sqlStatementIndex = 4453; // unlabeled_nonblock_stmt
var parseTree = parserType.GetMethod("Parse").Invoke(parser, new object[] { sqlScriptText, tokens });
//parseTree.GetType().GetMethod("PrintTree", new Type[] { parserGrammar.GetType() }).Invoke(parseTree, new object[] { parserGrammar });
var commandNodes = GetDescendants(parseTree)
.Select(n => ParseNodeFactory.CreateNode(n, sqlScriptText, tokens))
.Where(n => n != null);
var visitor = new GrammarNodeVisitor();
foreach (var commandNode in commandNodes)
{
commandNode.Accept(visitor);
}
}
public static class ParseNodeFactory
{
private const int queryBlockIndex = 3849; // query_block
private const int insertIndex = 3136; // insert
public static IParseNode CreateNode(object parseNode, string sqlScriptText, List<LexerToken> tokens)
{
var symbolIndex = GetPayloadIn(parseNode);
var parseData = new ParseData { ParseNode = parseNode, SqlScriptText = sqlScriptText, Tokens = tokens };
switch (symbolIndex)
{
case queryBlockIndex:
return new QueryBlock { ParseData = parseData };
case insertIndex:
return new Insert { ParseData = parseData };
default:
return null;
}
}
}
public class GrammarNodeVisitor : IParseNodeVisitor
{
public void VisitQueryBlock(QueryBlock queryBlock)
{
Console.WriteLine($"Visited query block: {GetCommandText(queryBlock.ParseData.ParseNode, queryBlock.ParseData.SqlScriptText, queryBlock.ParseData.Tokens)}");
}
public void VisitInsert(Insert insert)
{
Console.WriteLine($"Visited insert command: {GetCommandText(insert.ParseData.ParseNode, insert.ParseData.SqlScriptText, insert.ParseData.Tokens)}");
}
}
public interface IParseNodeVisitor
{
void VisitQueryBlock(QueryBlock queryBlock);
void VisitInsert(Insert insert);
}
public interface IParseNode
{
ParseData ParseData { get; }
void Accept(IParseNodeVisitor visitor);
}
public class ParseData
{
public object ParseNode { get; set; }
public string SqlScriptText { get; set; }
public List<LexerToken> Tokens { get; set; }
}
public class QueryBlock : IParseNode
{
public ParseData ParseData { get; set; }
public void Accept(IParseNodeVisitor visitor)
{
visitor.VisitQueryBlock(this);
}
}
public class Insert : IParseNode
{
public ParseData ParseData { get; set; }
public void Accept(IParseNodeVisitor visitor)
{
visitor.VisitInsert(this);
}
}
private static string GetCommandText(object parseNode, string sqlScriptText, List<LexerToken> tokens)
{
var from = (int)parseNodeType.GetProperty("From").GetValue(parseNode);
var to = (int)parseNodeType.GetProperty("To").GetValue(parseNode) - 1;
var begin = tokens[from].m_vBegin;
return sqlScriptText.Substring(begin, tokens[to].m_vEnd - begin);
}
private static IEnumerable<object> GetDescendants(object parseNode)
{
yield return parseNode;
foreach (var child in GetChildren(parseNode))
foreach (var descendant in GetDescendants(child))
yield return descendant;
}
private static int GetPayloadIn(object parseNode)
{
return (int)parseNodeType.GetProperty("PayloadIn").GetValue(parseNode);
}
private static IEnumerable<object> GetChildren(object parseNode)
{
return (IEnumerable<object>)parseNodeType.GetMethod("Children").Invoke(parseNode, null);
}

ProtoBuf-Linq error message “ Invalid field in source data: 0”

I've encountered the following issue while using protobuf-linq:
using (var stream = new MemoryStream())
{
SerializeMultiple(PrepareData(), stream);
}
private static void SerializeMultiple(IEnumerable<Person> persons, Stream stream)
{
foreach (var person in persons)
{
Serializer.Serialize(stream, person);
}
stream.Position = 0;
var q = RuntimeTypeModel.Default.AsQueryable<Person>(stream,null);
var results = from e in q
where e.Id % 2 == 0
select new { e.Id, e.Name };
Console.WriteLine("first : " + results.First().Id);
Console.ReadLine();
}
static IEnumerable<Person> PrepareData()
{
for (int i = 0; i < (int) 1e+04; i++)
{
yield return new Person {Id = i, Name= "John" + i, Address = "Address" + i*i};
}
}
[ProtoContract]
class Person
{
[ProtoMember(1)]
public int Id { get; set; }
[ProtoMember(2)]
public string Name { get; set; }
[ProtoMember(3)]
public string Address { get; set; }
}
The AsQueryable line throws the aforementioned exception:
Invalid field in source data: 0
Any thoughts on this matter?
It's not protobuf-linq error. When serializing items into a stream, you should use SerializeWithLengthPrefix to prefix every message with its length, to allow separate them. By default, protobuf-linq uses PrefixStyle.Base128. Below you can find a snippet making it right:
Serializer.SerializeWithLengthPrefix(stream, person, PrefixStyle.Base128);

Resources