使用 LINQ 构建查询
LINQ 运算符
LINQ 运算符 | 说明 | 读法 |
---|---|---|
获取数据源(from 子句) | 在使用生成的服务上下文和早期绑定时,请在生成的上下文中使用 IQueryable 实体集,例如 AccountSet。在不使用生成的上下文时,您可以通过组织服务上下文对象中的 CreateQuery 方法访问 Microsoft Dynamics 365 实体。 | |
join 子句 | join 子句表示内联。 使用该子句能够处理可通过共用的属性值联接的两个或多个实体。 | |
筛选(where 子句) | where 子句通常使用布尔表达式对结果应用筛选器。 该筛选器指定从源序列中排除哪些元素。 每个 where 子句只能包含针对单个实体类型的条件。 涉及多个实体的复合条件是无效的。 应在单独的 where 子句中筛选每个实体。 | |
orderby | orderby 运算符按指定顺序排列返回的查询属性。 | |
select 子句 | select 子句定义返回数据的窗体。 该子句根据查询表达式结果创建列集。 您还可以定义要使用的新对象的实例。 使用 select 子句新创建的对象不是在服务器上创建的,但它是一个本地实例。 |
LINQ 限制
LINQ 运算符 | 说明 | 读法 |
---|---|---|
join | 表示内部或外部联接。 仅支持左外部联接。 | |
from | 每个查询支持一个 from 子句。 | |
where | 该子句的左边必须是属性名称,该子句的右边必须是值。 不能将左边设置为常数。 该子句的两边均不能为常数。支持 String 函数Contains、StartsWith、EndsWith 和 Equals。 | |
groupBy | 不支持。 FetchXML 支持 LINQ 查询提供程序不提供的分组选项。详细信息: 使用 FetchXML 聚合 | |
orderBy | 支持按实体属性(如 Contact.FullName)排序。 | |
select | 支持匿名类型、构造函数和初始值设定项。 | |
last | 不支持 last 运算符。 | |
skip 和 take | 使用服务器端分页支持 skip 和 take。skip 值必须大于或等于 take 值。 | |
aggregate | 不支持。 FetchXML 支持 LINQ 查询提供程序不提供的聚合选项。详细信息: 使用 FetchXML 聚合 |
案例
public void LinqTest()
{
try
{
IOrganizationService _serviceProxy = SimulationCrmServer.GetOrganizationService();
OrganizationServiceContext orgContext = new OrganizationServiceContext(_serviceProxy);
#region 通过ServiceContext方式进行From
using (ServiceContext svcContext = new ServiceContext(_serviceProxy))
{
var query1 = from c in svcContext.ContactSet//如何链表,只能join和left join
join a in svcContext.AccountSet
on c.ContactId equals a.PrimaryContactId.Id
where a.Name.Contains("Contoso")
where c.LastName.Contains("Smith")
where a.Name != "马大哈"
select a;
foreach (var item in query1)
{
string name = item.Name;
}
//使用 Distinct 运算符
var query_distinct = (from c in svcContext.ContactSet
select c.LastName).Distinct();
foreach (var c in query_distinct)
{
System.Console.WriteLine(c);
}
//左链接
var query_join8 = from a in svcContext.AccountSet
join c in svcContext.ContactSet
on a.PrimaryContactId.Id equals c.ContactId
into gr
from c_joined in gr.DefaultIfEmpty()
select new
{
contact_name = c_joined.FullName,
account_name = a.Name
};
foreach (var c in query_join8)
{
System.Console.WriteLine(c.contact_name + " " + c.account_name);
}
//等于
var query_equals1 = from c in svcContext.ContactSet
where c.FirstName.Equals("Colin")
select new
{
c.FirstName,
c.LastName,
c.Address1_City
};
//不等于
var query_ne1 = from c in svcContext.ContactSet
where c.Address1_City != "Redmond"
select new
{
c.FirstName,
c.LastName,
c.Address1_City
};
//大于
var query_gt1 = from c in svcContext.ContactSet
where c.Anniversary > new DateTime(2010, 2, 5)
select new
{
c.FirstName,
c.LastName,
c.Address1_City
};
//使用大于等于和小于等于运算符
var query_gele1 = from c in svcContext.ContactSet
where c.CreditLimit.Value >= 200 &&
c.CreditLimit.Value <= 400
select new
{
c.FirstName,
c.LastName
};
//包含
var query_contains1 = from c in svcContext.ContactSet
where c.Description.Contains("Alpine")
select new
{
c.FirstName,
c.LastName
};
//不包含
var query_contains2 = from c in svcContext.ContactSet
where !c.Description.Contains("Coho")
select new
{
c.FirstName,
c.LastName
};
//以什么开头以什么结尾
var query_startswith1 = from c in svcContext.ContactSet
where c.FirstName.StartsWith("Bri")
select new
{
c.FirstName,
c.LastName
};
//使用 OrderBy 运算符
var query_orderby1 = from c in svcContext.ContactSet
where !c.CreditLimit.Equals(null)
orderby c.CreditLimit descending
select new
{
limit = c.CreditLimit,
first = c.FirstName,
last = c.LastName
};
//使用 First 和 Single 运算符 以下示例演示如何仅检索返回的第一条联系人记录以及仅检索与条件匹配的一条联系人记录。
Contact firstcontact = svcContext.ContactSet.First();
Contact singlecontact = svcContext.ContactSet.Single(c => c.ContactId == Guid.Empty);
//使用拉姆达表达式
var methodResults = svcContext.ContactSet.Where(a => a.LastName == "Smith");
var methodResults2 = svcContext.ContactSet.Where(a => a.LastName.StartsWith("Smi"));
//使用 Skip 和 Take 运算符(不分页)
var query_skip = (from c in svcContext.ContactSet
where c.LastName != "Parker"
orderby c.FirstName
select new
{
last = c.LastName,
first = c.FirstName
}).Skip(2).Take(2);
//FirstOrDefault 运算符返回序列中的第一个元素,如果未找到任何元素,则返回默认值。SingleOrDefault 运算符返回序列中单个特定的元素,如果未找到此元素,则返回该元素的默认值。 以下示例演示如何使用这些运算符。
Contact firstorcontact = svcContext.ContactSet.FirstOrDefault();
Contact singleorcontact = svcContext.ContactSet.SingleOrDefault(c => c.ContactId == Guid.Empty);
//对链接实体使用带条件的自联接
var query_joincond = from a1 in svcContext.AccountSet
join a2 in svcContext.AccountSet
on a1.ParentAccountId.Id equals a2.AccountId
where a2.AccountId == Guid.Empty
select new { Account = a1, Parent = a2 };
//在 Where 子句中使用转换
var query_wheretrans = from c in svcContext.ContactSet
where c.ContactId == Guid.Empty &&
c.Anniversary > DateTime.Parse("1/1/2010")
select new
{
c.FirstName,
c.LastName
};
//使用分页排序
var query_pagingsort1 = (from c in svcContext.ContactSet
where c.LastName != "Parker"
orderby c.LastName ascending,
c.FirstName descending
select new { c.FirstName, c.LastName })
.Skip(2).Take(2);
//使用 .Value 检索属性值
var query_value = from c in svcContext.ContactSet
where c.ContactId != Guid.Empty
select new
{
ContactId = c.ContactId != null ?
c.ContactId.Value : Guid.Empty,
NumberOfChildren = c.NumberOfChildren != null ?
c.NumberOfChildren.Value : default(int),
CreditOnHold = c.CreditOnHold != null ?
c.CreditOnHold.Value : default(bool),
Anniversary = c.Anniversary != null ?
c.Anniversary.Value : default(DateTime)
};
}
#endregion
#region 通过OrganizationServiceContext方式进行From(晚期绑定)
using (ServiceContext svcContext = new ServiceContext(_serviceProxy))
{
//Join
var query2 = from c in orgContext.CreateQuery("contact")
join a in orgContext.CreateQuery("account")
on c["contactid"] equals a["primarycontactid"]
select new
{
contact_name = c["fullname"],
account_name = a["name"]
};
foreach (var item in query2)
{
string fullname = item.account_name.ToString();
}
//Left join
var query_join9 = from a in orgContext.CreateQuery("account")
join c in orgContext.CreateQuery("contact")
on a["primarycontactid"] equals c["contactid"] into gr
from c_joined in gr.DefaultIfEmpty()
select new
{
account_name = a.Attributes["name"]
};
foreach (var c in query_join9)
{
System.Console.WriteLine(c.account_name);
}
//包含
var query_contains3 = from c in orgContext.CreateQuery("contact")
where ((string)c["description"]).Contains("Coho")
select new
{
firstname = c.Attributes["firstname"],
lastname = c.Attributes["lastname"]
};
foreach (var c in query_contains3)
{
System.Console.WriteLine(c.firstname + " " + c.lastname);
}
//不等于
var query_ne3 = from c in orgContext.CreateQuery("contact")
where !c["address1_city"].Equals(null)
select new
{
FirstName = c["firstname"],
LastName = c["lastname"],
Address1_City = c["address1_city"]
};
foreach (var c in query_ne3)
{
System.Console.WriteLine(c.FirstName + " " +
c.LastName + " " + c.Address1_City);
}
//使用 GetAttributeValue 方法
var list_getattrib1 = (from c in orgContext.CreateQuery("contact")
where c.GetAttributeValue<Guid?>("contactid") != Guid.Empty
select new
{
FirstName = c.GetAttributeValue<string>("firstname"),
LastName = c.GetAttributeValue<string>("lastname")
}).ToList();
foreach (var c in list_getattrib1)
{
System.Console.WriteLine(c.FirstName + " " + c.LastName);
}
//分页
int pageSize = 1;
foreach (var a in list_getattrib1.Skip(2 * pageSize).Take(pageSize))
{
System.Console.WriteLine(a.FirstName + " " + a.LastName);
}
}
#endregion
}
catch (Exception e)
{
throw;
}
}