我是C#的初学者(来自SQL背景(,所以这个问题中的一些术语可能不正确。提前道歉。
我正在尝试使用 C#/WPF/SQLite 创建一个食物消耗跟踪应用程序(允许您跟踪您吃了什么饭菜、计算卡路里等(。 我已使用 EF 中的"添加模型"向导创建了"数据库"部分和实体模型。
我有一个消费日志实体,像这样
public partial class ConsumptionLog
{
public int consumptionID { get; set; }
public Nullable<int> dayMealNumber { get; set; }
public Nullable<int> foodID { get; set; }
public Nullable<int> mealID { get; set; }
public Nullable<decimal> servings { get; set; }
public System.DateTime logDate { get; set; }
public virtual Meal Meal { get; set; }
public virtual Food Food { get; set; }
}
和
public partial class Food
{
public Food()
{
this.ConsumptionLogs = new HashSet<ConsumptionLog>();
this.MealContents = new HashSet<MealContent>();
}
public int foodID { get; set; }
public string store { get; set; }
public string brandName { get; set; }
public string foodName { get; set; }
public string foodUnit { get; set; }
public Nullable<decimal> foodNoOfUnits { get; set; }
public Nullable<decimal> calories { get; set; }
public Nullable<decimal> carb { get; set; }
public Nullable<decimal> sugar { get; set; }
public Nullable<decimal> protein { get; set; }
public Nullable<decimal> fat { get; set; }
public Nullable<decimal> fibre { get; set; }
public Nullable<decimal> gms { get; set; }
public Nullable<decimal> ml { get; set; }
public short isActive { get; set; }
public virtual ICollection<MealContent> MealContents { get; set; }
}
上面的代码是自动生成的。我正在尝试做的是在另一个类中扩展 ComsumptionLog,以添加更多属性。例如,这是一个片段...
public partial class ConsumptionLogView : ConsumptionLog
{
public ObservableCollection<ConsumptionLogView> CLViewList { get; set; }
string _FoodName;
public string FoodName
{
get
{
if (Food == null)
{
return "Total";
}
else
{
return Food.foodName.ToString() + " : "
+ Convert.ToDouble(Food.foodNoOfUnits).ToString() + " " + Food.foodUnit.ToString();
}
}
set
{
}
}
public decimal _Calories;
public decimal Calories
{
get
{
if (Food == null)
{
return _Calories;
}
else
{
return Convert.ToDecimal(Food.calories);
}
}
set
{
}
}
}
为了,我可以使用这样的东西
private void LoadConsumptionLogs()
{
FitnessLogDBEntities ctx = new FitnessLogDBEntities();
var consumptionList = (
from s in ctx.ConsumptionLogs
where s.logDate == LogDate.SelectedDate.Value
select s).ToList<ConsumptionLog>();
ObservableCollection<ConsumptionLogView> conLogViewColl =
(ObservableCollection<ConsumptionLogView>)consumptionList.Cast<ObservableCollection<ConsumptionLogView>>();
var consumptionItem = new ConsumptionLogView();
consumptionItem._Calories = GetTotalCals(conLogViewColl);
conLogViewColl.Add(consumptionItem);
ConsumptionLog.ItemsSource = conLogViewColl;
}
private decimal GetTotalCals(ObservableCollection<ConsumptionLogView> cons)
{
double Total = 0;
foreach (ConsumptionLogView con in cons)
{
Total += Convert.ToDouble(con.Calories);
}
return Convert.ToDecimal(Total);
}
显然,这是行不通的,并且在我尝试将基类 ObservableCollection (ConsumptionLog( 强制转换为派生类 (ConsumptionLogView( 时会跳闸。
我的问题是:
- 当我只有基类并使用 代码的总卡路里部分。只有这样,如果在那个时候,如果 我稍微修改了数据库结构,并在 VS 中刷新, 类和代码被覆盖。所以我开始走这条路 分隔附加代码。我试图做错了吗 像这样的东西(在类中分离代码(?
- 如果没有,我是否接近尝试填充基类 obs. coll. 并将集合内容"复制"到派生类 obs. 集合中?我想既然ConsumptionLogView拥有所有的消耗+一些,我就可以投射它了。
我在SO和其他地方搜索,但不确定要搜索什么,因此任何帮助将不胜感激。如果有指向其他工作示例的指针,那也是我可以开始的地方。
提前感谢, S
您不必使用继承来扩展类。在 C# 中扩展类的第二种方法是使用分部类。这意味着一个类由多个文件组成。通常,自动生成的类已经是部分的。这意味着扩展类非常简单。假设代码生成器创建了ComsumptionLog.cs(请注意partial
标识符(
public partial class ConsumptionLog
{
//Some properties
}
你只需要创建第二个文件,如ComsumptionLogExtension.cs
public partial class ConsumptionLog
{
//Additional properties and methods
}
以及您需要的所有其他属性和方法。有关更多信息,请查看 Microsoft 对分部类的描述。这样,您就不需要强制转换任何类型,因为类仍然相同。如果将扩展文件保存在与生成的文件不同的文件夹中,则代码生成器在生成运行期间不应触摸它。请注意,命名空间必须相同。
我认为这种方法应该以一种非常干净和简单的方式解决你的问题。