我有一个使用EF Core的MVC项目。在我的控制器中,我通过url接收参数,其中之一是private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (dataGridView1.CurrentCell.ColumnIndex != 0 && dataGridView1.CurrentCell.RowIndex != -1)
{
dataGridView1[dataGridView1.CurrentCell.ColumnIndex, dataGridView1.CurrentCell.RowIndex].Value = 1;
int index = dataGridView1.CurrentCell.RowIndex;
//calls the method to update the request.
DataStoreUpdate(index);
}
}
//update method for reflecting to dataStore when clicked on the dataGridView cell
private void DataStoreUpdate(int index)
{
IPAddress address = IPAddress.Parse(textBox1.Text);
int port = Convert.ToInt32(textBox2.Text);
TcpListener slaveTcpListener = new TcpListener(address, port);
slaveTcpListener = new TcpListener(address, port);
slave.DataStore.CoilDiscretes[index] = true;
slaveTcpListener.Stop();
}
//Following is the code for creating Modbus TcpSlave and creating a datastore for different registers.
private void Button1_Click(object sender, EventArgs e)
{
try
{
byte slaveAddress = Convert.ToByte(textBox3.Text);
IPAddress address = IPAddress.Parse(textBox1.Text);
int port = Convert.ToInt32(textBox2.Text);
// create and start the TCP slave
TcpListener slaveTcpListener = new TcpListener(address, port);
slaveTcpListener.Start();
slave = ModbusTcpSlave.CreateTcp(slaveAddress, slaveTcpListener);
slave.Listen();
slave.DataStore = DataStoreFactory.CreateDefaultDataStore();
DataStore dataStore = slave.DataStore;
slave.ModbusSlaveRequestReceived += new EventHandler<ModbusSlaveRequestEventArgs>(Modbus_Request_Event);
slave.DataStore.DataStoreWrittenTo += new EventHandler<DataStoreEventArgs>(DataStoreWrittenTo);
}
catch
{
MessageBox.Show("Error in connection");
}
}
。我有这样格式的客户表:
searchQuery
请注意,客户要么是雇主,要么是个人,而不是两者。 (相应的字段将为NULL)。这是我正在使用的查询:
id | empId | empName | personId | personFirstName | personLastName
这项工作虽然不是我想要的方式。如果用户搜索“ Jhon Pots”,而客户是一个人,则它将检查名字是否包含“ Jhon Pots”或姓氏,而不是检查名字是否包含“ Jhon”和姓氏“点”。
我可以合并collectionBeforePaging = _context.Customers
.Where(a => (a.Employer == null ? (a.Person.FirstName.Contains(searchQueryForWhereClause) ||
a.Person.LastName.Contains(searchQueryForWhereClause) ||
a.PersonId.ToString().Contains(searchQueryForWhereClause))
: (a.Employer.Name.Contains(searchQueryForWhereClause) ||
a.EmployerId.ToString().Contains(searchQueryForWhereClause))));
和firstName
,但是必须完全匹配(即,它不会匹配名为“ Jhon S. Pots”的客户)
我还考虑过使用lastName
方法分解searchQuery,但是我不知道如何正确地将它与EF Where子句结合起来。(我无法为每个对象使用foreach循环和过滤器字符串,因为它将按每个字符串过滤我的结果,而不是使用Split
逻辑运算符)
有人知道我该如何实现吗?
答案 0 :(得分:1)
假设您的“客户”表具有唯一的ID。对搜索字符串执行拆分,然后为每个拆分仅返回实际客户ID的列表。将ID一起添加到列表中,然后使用该ID列表获取匹配的客户
答案 1 :(得分:1)
要执行数据库方面的比较,您可以使用EF.Functions.Like()方法。
使用空格作为定界符分割搜索词,迭代搜索词并在执行之前在查询中添加where子句:
string[] searchTerms = searchQueryForWhereClause.Split(' ');
var query = _context.Customers.AsQueryable();
foreach (string searchTerm in searchTerms)
{
query = query.Where(x => EF.Functions.Like(x.FirstName, $"%{searchTerm}%"
|| EF.Functions.Like(x.LastName, $"%{searchTerm}%"
|| EF.Functions.Like(x.PersonId, $"%{searchTerm}%"
|| EF.Functions.Like(x.Employer.Name, $"%{searchTerm}%"
|| EF.Functions.Like(x.EmployerId, $"%{searchTerm}%");
}
答案 2 :(得分:1)
您需要先分割字符串,然后根据结果数组中的任何项目是否与每个字段匹配来进行查询:
var keywords = searchQuery.Split(' ');
然后:
collectionBeforePaging = _context.Customers
.Where(a => a.Employer == null
? keywords.Any(k =>
a.Person.FirstName.Contains(k) ||
a.Person.LastName.Contains(k) ||
a.PersonId.ToString().Contains(k))
: keywords.Any(k =>
a.Employer.Name.Contains(k) ||
a.EmployerId.ToString().Contains(k)));